{"record":{"id":"b940fee3f977e9b7","repo":"hashicorp/nomad","slug":"must-have-at-least-client-or-server-mode-enabled","errorCode":null,"errorMessage":"must have at least client or server mode enabled","messagePattern":"must have at least client or server mode enabled","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/agent.go","lineNumber":180,"sourceCode":"\t// Global logger should match internal logger as much as possible\n\tgolog.SetFlags(golog.LstdFlags | golog.Lmicroseconds)\n\n\tif err := a.setupConsuls(config.Consuls); err != nil {\n\t\treturn nil, fmt.Errorf(\"Failed to initialize Consul client: %v\", err)\n\t}\n\n\tif err := a.setupServer(); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := a.setupClient(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := a.setupEnterpriseAgent(logger); err != nil {\n\t\treturn nil, err\n\t}\n\tif a.client == nil && a.server == nil {\n\t\treturn nil, fmt.Errorf(\"must have at least client or server mode enabled\")\n\t}\n\n\t// If the agent is configured with TLS, set up the TLS metrics process to\n\t// emit certificate expiry metrics and start this.\n\tif !a.config.TLSConfig.IsEmpty() {\n\t\ttlsMetrics, err := newTLSMetrics(a.logger, a.config.TLSConfig, nil)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to set up TLS expiration metrics: %w\", err)\n\t\t}\n\t\ta.tlsMetrics = tlsMetrics\n\t\ttlsMetrics.start(a.config.Telemetry.collectionInterval)\n\t}\n\n\treturn a, nil\n}\n\n// convertServerConfig takes an agent config and log output and returns a Nomad\n// Config. There may be missing fields that must be set by the agent. To do this","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/agent.go#L162-L198","documentation":"NewAgent validates that the agent was constructed with at least one mode: client, server, or both. After enterprise setup, if both a.client and a.server are nil, no useful work can be done, so construction fails. This guards against an agent config that disables every role.","triggerScenarios":"Calling NewAgent (directly or via the `nomad agent` command via setupAgent/start) with a config where client.enabled=false and server.enabled=false, or where client/server setup silently skipped creation.","commonSituations":"Hand-edited config files setting both enabled = false; templates or env-based config generation accidentally omitting both stanzas; launching an agent binary without any role flags (e.g. missing -client/-server).","solutions":["Set client { enabled = true } or server { enabled = true } in the agent config (or pass -client / -server flags).","Check that generated config (env vars, templates) actually enables one mode before startup.","If embedding NewAgent in Go, ensure Agent.config has ClientConfig or ServerConfig populated and enabled before calling NewAgent."],"exampleFix":"// before (config.hcl)\nclient { enabled = false }\nserver { enabled = false }\n// after\nclient { enabled = true }","handlingStrategy":"validation","validationCode":"// Go: before calling agent.NewAgent\ncfg := &config.Agent{\n    Client: clientCfg,\n    Server: serverCfg,\n}\nif (clientCfg == nil || !clientCfg.Enabled) && (serverCfg == nil || !serverCfg.Enabled) {\n    return fmt.Errorf(\"agent config must enable client or server mode\")\n}\na, err := agent.NewAgent(cfg, log)","typeGuard":"func hasEnabledMode(cfg *config.Agent) bool {\n    if cfg == nil { return false }\n    c := cfg.Client != nil && cfg.Client.Enabled\n    s := cfg.Server != nil && cfg.Server.Enabled\n    return c || s\n}","tryCatchPattern":"a, err := agent.NewAgent(cfg, logger)\nif err != nil {\n    if strings.Contains(err.Error(), \"at least client or server mode\") {\n        logger.Error(\"no agent mode enabled; check client/server stanzas\")\n    }\n    return err\n}","preventionTips":["Always pass -client and/or -server on the CLI, or enable one stanza in the config file.","Validate generated configs (nomad agent -config ... in CI with a dry check) before deploy.","Keep client enabled even on server-only nodes when unsure — servers can also run as clients."],"tags":["nomad","config","startup"],"backgroundTag":"missing-required-config","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}