hashicorp/nomad · error

missing state

Error message

missing state

What it means

ACLOIDCCompleteAuthRequest.Validate requires State to be non-empty. The opaque state value issued by the OIDC provider (and tracked by Nomad) protects against CSRF and links the callback to the original request; an empty State yields 'missing state'.

Source

Thrown at nomad/structs/acl.go:2387

	RedirectURI string

	WriteRequest
}

// Validate ensures the request object contains all the required fields in
// order to complete the OIDC authentication flow.
func (a *ACLOIDCCompleteAuthRequest) Validate() error {

	var mErr multierror.Error

	if a.AuthMethodName == "" {
		mErr.Errors = append(mErr.Errors, errors.New("missing auth method name"))
	}
	if a.ClientNonce == "" {
		mErr.Errors = append(mErr.Errors, errors.New("missing client nonce"))
	}
	if a.State == "" {
		mErr.Errors = append(mErr.Errors, errors.New("missing state"))
	}
	if a.Code == "" {
		mErr.Errors = append(mErr.Errors, errors.New("missing code"))
	}
	if a.RedirectURI == "" {
		mErr.Errors = append(mErr.Errors, errors.New("missing redirect URI"))
	}
	return mErr.ErrorOrNil()
}

// ACLLoginResponse is the response when the auth flow has been
// completed successfully.
type ACLLoginResponse struct {
	ACLToken *ACLToken
	WriteMeta
}

// ACLLoginRequest is the request object to begin auth with an external

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Read the state query parameter from the provider callback and set State on the request
  2. Fix the OIDC provider client config so state is included in the redirect
  3. Verify the full callback URL (including state) reaches your handler

Example fix

// before
req := &structs.ACLOIDCCompleteAuthRequest{AuthMethodName: m, ClientNonce: n, Code: r.URL.Query().Get("code")}
// after
req := &structs.ACLOIDCCompleteAuthRequest{AuthMethodName: m, ClientNonce: n, State: r.URL.Query().Get("state"), Code: r.URL.Query().Get("code")}
Defensive patterns

Strategy: validation

Validate before calling

if req.State == "" { return errors.New("State from the provider callback is required") }

Type guard

func hasState(req *structs.ACLOIDCCompleteAuthRequest) bool { return req != nil && req.State != "" }

Try / catch

if err := req.Validate(); err != nil {
  if strings.Contains(err.Error(), "missing state") { /* treat as CSRF-suspect callback; abort login */ }
}

Prevention

When it happens

Trigger: Calling the OIDC complete-auth endpoint with ACLOIDCCompleteAuthRequest.State == "", e.g. the user lands on the callback without a state query parameter or the handler drops it when building the request.

Common situations: IdP redirects to the callback without state (misconfigured provider); callback handler only reads 'code'; user manually pasting a truncated callback URL; state lost in cross-domain redirects.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/1ba5770c1d551c31. Report an issue: GitHub.