# Fix "not supported on device" DeviceErrors in PennyLane
Use this when executing a QNode raises `pennylane.exceptions.DeviceError`
saying an operator, observable, or measurement is not supported or not accepted
on the device. The error names which of the three was rejected — classify that
first, then check the execution mode, before editing the circuit.
## 1. Read the error — it tells you which of three things is rejected
| Error pattern | What's rejected | Typical cause |
|---|---|---|
| `Operator X(wires=[...]) not supported on device and does not provide a decomposition.` (older versions: `Gate X not supported on device ...`) | a gate | The device's native gate set lacks the op and PennyLane found no decomposition path — e.g. `DeviceError: Gate RX not supported on device default.gaussian` |
| `Observable ... not supported on device` | an observable inside `qml.expval`/`qml.var` | The observable is outside the device's accepted set |
| `Measurement ... not accepted for analytic simulation on device.` | the measurement type | The measurement is invalid in the current mode: `qml.state()`/`qml.density_matrix()` on hardware (simulator-only measurements), or sample-based measurements with `shots=None` |
## 2. Classify, then check the mode
- **Op rejected**: CV devices (`default.gaussian`) support only Gaussian
operations — use `qml.Rotation` instead of `qml.RX`, or move the circuit to
`default.qubit`. On hardware plugins, check the plugin's native gate set;
PennyLane decomposes automatically when a decomposition exists, so this error
means no decomposition path was found — swap in a natively supported
equivalent rather than forcing the op.
- **Observable rejected**: rewrite the observable from supported pieces
(e.g. a `qml.Hamiltonian`/`qml.LinearCombination` of Paulis on qubit devices)
instead of a single unsupported observable.
- **Measurement rejected**: `qml.state()` and `qml.density_matrix()` are
simulator-only — on hardware or remote devices (e.g. Strawberry Fields
remote) they are rejected outright; use `qml.expval`, `qml.probs`, or
`qml.sample` instead. Sample-based measurements (`qml.sample`,
`qml.counts`) need finite shots: `qml.device("default.qubit", wires=2,
shots=1000)`. Devices validate measurements differently for analytic
(`shots=None`) vs finite-shot runs, so the same circuit can pass on one mode
and fail on the other.
## 3. Diagnose before editing
```python
import pennylane as qml
specs = qml.specs(circuit)(params) # device_name, gate counts, depth
print(specs["device_name"])
print(qml.draw(circuit, wire_order=dev.wires)(params))
```
`qml.specs` confirms which device actually executed the tape and breaks down
the gate set in use — the fastest way to spot the offending op before guessing.
## 4. Checklist for the failing execution
1. Copy the exact DeviceError; identify op / observable / measurement from the
table in step 1.
2. Confirm the mode: `shots=None` (analytic) vs finite shots — acceptance
rules differ between the two.
3. Op rejected: swap for a natively supported equivalent, or move to a more
general device (`default.qubit`).
4. Measurement rejected: `qml.state()` means simulator only; sampling means
set `shots`.
5. Re-run `qml.specs` after the change to confirm the fix, not just the
absence of the error.