hashicorp/nomad · error

default auth config text could not be deserialized: %v

Error message

default auth config text could not be deserialized: %v

What it means

In `nomad setup consul`, renderAuthMethod unmarshals an embedded default JSON template (consulAuthConfigBody) into a map to build the JWT auth method. If the embedded constant is not valid JSON, this error wraps the json.Unmarshal failure. Since the template ships with the binary, this almost always indicates a corrupted or locally modified build.

Source

Thrown at command/setup_consul.go:430

func (s *SetupConsulCommand) authMethodExists(authMethodName string) bool {
	qo := &api.QueryOptions{}
	if s.consulEnt {
		// auth methods are created in the default ns
		qo.Namespace = "default"
	}

	existingMethods, _, _ := s.client.ACL().AuthMethodList(qo)
	return slices.ContainsFunc(
		existingMethods,
		func(m *api.ACLAuthMethodListEntry) bool { return m.Name == authMethodName })
}

func (s *SetupConsulCommand) renderAuthMethod(name string, desc string) (*api.ACLAuthMethod, error) {
	authConfig := map[string]any{}
	err := json.Unmarshal(consulAuthConfigBody, &authConfig)
	if err != nil {
		return nil, fmt.Errorf("default auth config text could not be deserialized: %v", err)
	}

	authConfig["JWKSURL"] = s.jwksURL
	authConfig["BoundAudiences"] = []string{consulAud}
	authConfig["JWTSupportedAlgs"] = []string{"RS256"}

	if s.jwksCACertPath != "" {
		caCert, err := os.ReadFile(s.jwksCACertPath)
		if err != nil {
			return nil, fmt.Errorf("could not read -jwks-certfile: %v", err)
		}
		authConfig["JWKSCACert"] = string(caCert)
	}

	method := &api.ACLAuthMethod{
		Name:          name,
		Type:          "jwt",
		DisplayName:   name,

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Rebuild from a pristine upstream checkout: `git checkout -- command/setup_consul.go && make build` (or re-download the official release binary).
  2. Verify the binary isn't modified: compare checksum against the official release for your version.
  3. If you intentionally customized consulAuthConfigBody, validate the JSON: `echo '<your json>' | jq .` and fix syntax errors.
  4. Work around by configuring the Consul auth method manually via `consul acl auth-method create` with your own -config instead of running nomad setup.

Example fix

// before (corrupted embedded constant)
const consulAuthConfigBody = `{"JWTSupportedAlgs": ["RS256",,]}`
// after
const consulAuthConfigBody = `{"JWTSupportedAlgs": ["RS256"]}`
Defensive patterns

Strategy: type-guard

Validate before calling

// validate the embedded template before use
if !json.Valid([]byte(consulAuthConfigBody)) {
    return fmt.Errorf("consulAuthConfigBody is not valid JSON")
}

Type guard

func validJSONObject(b []byte) bool {
    var m map[string]any
    return json.Unmarshal(b, &m) == nil && m != nil
}

Try / catch

authConfig := map[string]any{}
if err := json.Unmarshal(consulAuthConfigBody, &authConfig); err != nil {
    return fmt.Errorf("default auth config text could not be deserialized: %v", err)
}

Prevention

When it happens

Trigger: json.Unmarshal(consulAuthConfigBody, &authConfig) fails — the compiled-in auth config JSON is malformed, typically after a source modification, bad merge, or build from an incomplete/corrupted checkout.

Common situations: Building Nomad from a fork or patched source where command/setup_consul.go's embedded JSON was edited and broke syntax; vendoring tools or code generators corrupting string constants; a bad merge conflict resolution leaving partial JSON in the constant.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


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