How to Fix "One of the differentiated Tensors does not require grad"

You called torch.autograd.grad(outputs, inputs) and one entry in inputs has requires_grad=False. The output is fine, it has a graph. The tensor you asked to differentiate with respect to was never marked. Fix it with x.requires_grad_(True) placed before the forward pass that produces the output, then run the forward pass again.

Autograd records edges during the forward pass. A flag set after the forward pass changes the tensor, not the graph that already exists.

Check your combination

Answer five questions about the call that failed. The tool prints the exact exception torch 2.8.0 raises for that combination, or tells you the call is valid, and gives the fix. All 48 combinations were run on CPU and the strings are copied from the real exceptions. The scenario assumes a model with trainable parameters, so the output has a graph unless you cut it yourself.

Runs entirely in your browser. Nothing you select is sent anywhere.

The error and its two siblings

RuntimeError: One of the differentiated Tensors does not require grad

Note the capital T in Tensors. That is how torch 2.8.0 spells it, and the spelling helps you tell it apart from two messages that look similar but point at a different mistake.

MessageWhat is wrong
One of the differentiated Tensors does not require gradAn inputs entry has requires_grad=False. The output is fine.
element 0 of tensors does not require grad and does not have a grad_fnThe output has no graph. It was computed under torch.no_grad(), detached, or built entirely from tensors that do not require grad.
One of the differentiated Tensors appears to not have been used in the graph. Set allow_unused=True if this is the desired behavior.The input requires grad, but nothing on the path to the output reads it.

Only torch.autograd.grad raises the first and third. loss.backward() takes no inputs argument, so it never inspects your tensor. With a plain input it runs, fills the parameter gradients, and leaves x.grad as None. If that is the symptom you have, the page on gradient is None covers it.

Cause 1, the input is a plain leaf

This is the saliency map, adversarial example and input attribution case. You want the gradient of the model output with respect to the input, but the input came from a DataLoader or torch.randn with the default requires_grad=False.

model = nn.Linear(4, 1)
x = torch.randn(2, 4)
y = model(x).sum()
torch.autograd.grad(y, x)
# RuntimeError: One of the differentiated Tensors does not require grad

x = torch.randn(2, 4, requires_grad=True)   # or x.requires_grad_(True)
y = model(x).sum()
(g,) = torch.autograd.grad(y, x)             # g.shape == (2, 4)

The output y has a grad_fn in both versions because the weights of model require grad. That is why you get the differentiated Tensors message rather than the element 0 message. Freeze every parameter as well and the same plain x produces the element 0 message instead, because then nothing in the graph requires grad.

Cause 2, requires_grad set after the forward pass

The obvious repair is to set the flag when you see the error. If you set it after the forward pass has already run, the error changes but the call still fails.

x = torch.randn(2, 4)
y = model(x).sum()
x.requires_grad_(True)        # too late
torch.autograd.grad(y, x)
# RuntimeError: One of the differentiated Tensors appears to not have been used
# in the graph. Set allow_unused=True if this is the desired behavior.

torch.autograd.grad(y, x, allow_unused=True)
# (None,)   no error, no gradient either

The graph behind y was recorded while x did not require grad, so there is no edge from x into it. Flipping the flag makes x a valid input, but an unused one. Adding allow_unused=True silences the check and returns None, which is the wrong fix for this cause. Move the requires_grad_(True) line above the forward pass and the same call returns a (2, 4) gradient.

Cause 3, one bad tensor in a list

inputs accepts a sequence. The check runs over every entry and stops at the first failure, and the message does not say which entry failed.

a = torch.randn(3, requires_grad=True)
b = torch.randn(3)
y = (a * b).sum()
torch.autograd.grad(y, [a, b])
# RuntimeError: One of the differentiated Tensors does not require grad

Print [t.requires_grad for t in inputs] before the call. When the list is model.parameters(), look for layers you froze earlier with requires_grad_(False) and filter them out, or pass only the parameters you want.

Cause 4, a tensor built inside no_grad

The tensor does not have to be a leaf. An intermediate computed inside torch.no_grad() comes out with requires_grad=False, and differentiating with respect to it raises the same message even when the final output has a graph.

x = torch.randn(3, requires_grad=True)
with torch.no_grad():
    h = x * 2
w = torch.randn(3, requires_grad=True)
y = (h * w).sum()
torch.autograd.grad(y, h)
# RuntimeError: One of the differentiated Tensors does not require grad

Compute h outside the no_grad block, or differentiate with respect to x after doing so.

Gradient penalty, WGAN-GP style

A gradient penalty differentiates the critic output with respect to interpolated samples and then backpropagates through that gradient. Two things must be true. The interpolate must require grad before it enters the critic, and create_graph=True must be set so the gradient itself has a graph.

eps = torch.rand(5, 1)
interp = (eps * real + (1 - eps) * fake).requires_grad_(True)
d_out = D(interp)
(grads,) = torch.autograd.grad(
    outputs=d_out, inputs=interp,
    grad_outputs=torch.ones_like(d_out),
    create_graph=True, retain_graph=True)
gp = ((grads.norm(2, dim=1) - 1) ** 2).mean()
gp.backward()

Run on torch 2.8.0 this prints gp 0.6463, grads.requires_grad True, D[0].weight.grad is None: False, so the penalty reached the critic weights. Drop the requires_grad_(True) and the autograd.grad line raises the differentiated Tensors error. Keep it but set create_graph=False and the call succeeds, then gp.backward() raises element 0 of tensors does not require grad and does not have a grad_fn, because grads is now a constant.

PINN derivatives with a scalar-output helper

Physics-informed networks need du/dx and d2u/dx2 at every collocation point. torch.autograd.grad wants a scalar output or an explicit grad_outputs. Summing the output is the usual trick, and it is exact here because each row of u depends only on its own row of x.

x = torch.linspace(0, 1, 5).view(-1, 1).requires_grad_(True)
u = net(x)

def d(f, wrt):
    return torch.autograd.grad(f.sum(), wrt, create_graph=True)[0]

u_x = d(u, x)
u_xx = d(u_x, x)
loss = ((u_xx + u) ** 2).mean()
loss.backward()

Output on torch 2.8.0 is u_x shape (5, 1), u_xx shape (5, 1), u_x.requires_grad True, loss 0.0780. Build x from torch.linspace without the requires_grad_(True) and the first d(u, x) raises the differentiated Tensors error. Leave create_graph=True off the first derivative and the second call raises the element 0 message instead, since u_x then has no graph.

What PyTorch 2.8.0 actually raises

Each row below was run on torch 2.8.0, CPU, and the result column is the exception text or the printed value. The model in every row is an nn.Linear with trainable weights unless the row says otherwise.

SetupResult
autograd.grad(y, x), x plain leaf, y through trainable wRuntimeError: One of the differentiated Tensors does not require grad
autograd.grad(y, x), x plain leaf, y = (x * 2).sum()RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn
autograd.grad(y, [a, b]), only b plainRuntimeError: One of the differentiated Tensors does not require grad
saliency, model(x) with plain xRuntimeError: One of the differentiated Tensors does not require grad
saliency, x.requires_grad_(True) before forwardValid, grad shape (2, 4)
x.requires_grad_(True) after forwardRuntimeError: One of the differentiated Tensors appears to not have been used in the graph. Set allow_unused=True if this is the desired behavior.
after forward, plus allow_unused=TrueRuns, returns (None,)
x requires grad, y computed from z, not xRuntimeError: One of the differentiated Tensors appears to not have been used in the graph. Set allow_unused=True if this is the desired behavior.
y computed under torch.no_grad()RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn
y detachedRuntimeError: element 0 of tensors does not require grad and does not have a grad_fn
all params frozen, x plainRuntimeError: element 0 of tensors does not require grad and does not have a grad_fn
all params frozen, x requires gradValid, grad shape (2, 4)
y detached and x plain, both wrongRuntimeError: element 0 of tensors does not require grad and does not have a grad_fn (the output is checked first)
non-leaf h built under no_grad, grad wrt hRuntimeError: One of the differentiated Tensors does not require grad
y.backward() with plain xRuns, x.grad is None, weight.grad shape (1, 4)
y.backward(), requires_grad set after forwardRuns, x.grad is None
y.backward(), y under no_gradRuntimeError: element 0 of tensors does not require grad and does not have a grad_fn
autograd.grad(y, x), y is (3,) and no grad_outputsRuntimeError: grad can be implicitly created only for scalar outputs
WGAN-GP, interpolate without requires_grad_RuntimeError: One of the differentiated Tensors does not require grad
WGAN-GP, create_graph=False, then gp.backward()RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn
PINN, plain linspace xRuntimeError: One of the differentiated Tensors does not require grad

When the output has no graph and the input is plain, the output check wins. Fix the element 0 message first and you may then meet the differentiated Tensors message for the same tensor.

The inputs contract

The reference for torch.autograd.grad describes inputs as the tensors "w.r.t. which the gradient will be returned (and not accumulated into .grad)", and describes allow_unused this way: "If False, specifying inputs that were not used when computing outputs (and therefore their grad is always zero) is an error." The same page notes that retain_graph defaults to the value of create_graph, which is why the gradient penalty above does not need a separate flag for the first call. Neither error string appears on that page. Treat the strings on this page as observed behaviour on torch 2.8.0.

The three conditions the engine checks, in order, are these. The output must have a grad_fn. Every input must have requires_grad=True. Every input must be reachable from the output, unless allow_unused=True. Satisfy all three and the call returns one gradient per input.

Browse the PyTorch Error Database

Built by Michael Lip. Behaviour verified against torch 2.8.0 on 6 September 2026.

By the same builder: GitHub, theluckystrike BeLikeNative, Grammar AI EarlyThunder, Dev Blog Bug Bounty Reality Zovo, AI Dev Tools