skip to content

An SNMP SetRequest with three variable bindings returns inconsistentValue with error-index 2; which of the three changes did the agent apply, and why?

level: seniorimportance: nice to knowfreq 10%

answer

  1. validate everything before changing anything
  2. as if simultaneous
  3. commit failure means undo
  4. undoFailed leaves state unknown
  5. a retried create meets its own row

basics

~20 s

An SNMP agent assigns nothing: RFC 3416 has it validate every SetRequest binding before assigning any, so a validation error such as inconsistentValue on binding 2 leaves all three unchanged; the manager fixes that binding and resends the request.

solid answer

~40 s

The agent applied none of them. RFC 3416 processes a `SetRequest` as a conceptual two-phase operation: first every binding is validated, then, only if all pass, every variable is assigned **as if simultaneously**. `inconsistentValue` is a validation result, so the second phase never ran; `error-index` 2 names the second binding of the request, counting from one. Failures that can happen after validation have their own codes: `commitFailed` means an assignment failed and the others were undone, with `error-index` on the failed binding; `undoFailed`, with `error-index` 0, means the undo itself failed and the device's state is unknown, so the manager must read the objects back. Retries need care too: a retransmitted Set whose first reply was lost is processed again, and a row-creating `createAndGo` then fails with `inconsistentValue` because the row already exists.

go deeper

for a junior

Recall that an SNMP SetRequest writes all of its bindings or none of them, and that error-index names the binding that failed, counting from one.

for a middle

Explain the validate-then-assign phases, the difference between wrongValue and inconsistentValue, and what commitFailed and undoFailed tell the manager.

for a senior

Handle the unhappy paths in production: read back after undoFailed or a lost reply, and expect a retried createAndGo to fail on the row its first attempt created.

for a principal

Decide when SNMP Set is acceptable for configuration at all, given its retry semantics and partial-failure cases, and what verification a change pipeline must add on top.

## SetRequest is all or nothing A `SetRequest-PDU` is SNMP's only write. It carries a variable-binding list in which every value matters, and RFC 3416 defines its processing so that a multi-object change either happens completely or not at all. That matters because many configuration changes need several objects to change together: an address and its mask, the columns of a new table row, a threshold and the action tied to it. ## The two conceptual phases RFC 3416 describes Set processing as **two conceptual phases**, validation then assignment, preceded by a size check; it lets an implementation split the phases further if it needs to. 1. **Size check (before either phase).** Before anything else, the agent works out whether a Response echoing these bindings would fit; if not, it replies `tooBig` with `error-index` 0 and an empty binding list, and stops. 2. **Phase one, validation.** Each binding is checked in order until all pass or one fails. The first failure sets `error-status` and puts that binding's position, counting from one, in `error-index`. 3. **Phase two, assignment.** Only if every binding validated does the agent create variables where needed and assign every value, **as if simultaneously** with respect to the others. So with `inconsistentValue` on binding 2, the request never reached step 3: bindings 1 and 3 were not applied either, and the manager can correct binding 2 and resend all three. ## What each validation code tells you The validation checks run in a fixed order, so the code says how far the binding got: | error-status | What it means | |---|---| | `noAccess` | the name is outside the MIB view this request may write | | `notWritable` | no variable with this name can be written or created, whatever the value | | `wrongType`, `wrongLength`, `wrongEncoding` | the value's ASN.1 type, length or encoding does not fit the object | | `wrongValue` | no circumstance would ever allow this value | | `noCreation` | this instance does not exist and could never be created | | `inconsistentName` | this instance does not exist and cannot be created right now | | `inconsistentValue` | the value could be valid, but not in the current state | | `resourceUnavailable` | assigning it needs a resource the agent does not have now | | `genErr` | any other failure | The distinction between `wrongValue` and `inconsistentValue` is the useful one in operations: the first means "never", the second "not now", typically because other objects or a row's state make the value unacceptable at this moment. ## Failures after validation Validation cannot catch everything; hardware can refuse a change that looked legal. - **`commitFailed`.** An assignment failed after all validations passed. The agent undoes every other assignment, so the result is still "nothing changed", and `error-index` names the binding whose assignment failed. - **`undoFailed`.** The agent could not undo all the assignments. `error-index` is **0**, and the device may be partly changed. The manager must read the affected objects back before doing anything else. RFC 3416 strongly encourages implementations to avoid both codes and says they are not a licence to take the easy way out. Two more edge rules: if the same variable is named twice with different values in one request, which assignment wins is implementation-specific; and SNMPv1 (RFC 1157, now Historic) reported most Set failures as `noSuchName` or `badValue`, never actually generating `readOnly`, as RFC 3584 notes. ## Retries and row creation A Set travels in a UDP datagram, and the reply can be lost after the agent has applied the change. If the manager retransmits, the agent processes the request again; nothing in the SetRequest procedure checks whether a `request-id` was already handled. - For a plain assignment, setting the same value twice is harmless. - For **row creation** with the `RowStatus` textual convention (RFC 2579), it is not. Setting a status column to `createAndGo` when the row does not exist creates it and makes it `active`; setting `createAndGo` on a row that already exists returns `inconsistentValue`. So a retried creation can report failure even though the first attempt succeeded. RFC 2579 itself advises that, on `inconsistentValue`, the manager retrieve the row to learn whether a required column was missing or the row already existed. ## What a robust manager does - Put every object of one logical change in **one** SetRequest, so the agent's atomicity covers it. - Treat validation errors as "nothing applied": fix the binding at `error-index` and resend the whole request. - Treat `undoFailed` and a timed-out Set as "state unknown": read back before retrying.

  • Why should related SNMP changes go in one SetRequest rather than three?
    Atomicity covers only the bindings in one request. Three separate Sets can leave the device half-changed if the second fails after the first succeeded, and the manager then has to undo the first itself. One request with three bindings either applies all three or none, apart from the rare `undoFailed` case.
  • An SNMP Set to a read-only object visible in the request's view fails; which error-status should come back?
    `notWritable`, with `error-index` on that binding: the variable exists but cannot be modified whatever value is given. If the object were outside the MIB view the request may write, the earlier check would fire first and return `noAccess`.

saying these in an interview costs you the question

  • Bindings before the failing one in a SetRequest have already been applied.
  • commitFailed means the change partly applied and must be rolled back by hand.
  • An SNMP agent recognises a retransmitted Set by its request-id and skips it.
  • error-index 0 on undoFailed points at the first binding.
  • wrongValue and inconsistentValue mean the same thing.