{"record":{"id":"253519555490c564","repo":"thanos-io/thanos","slug":"endpoint-address-must-be-set","errorCode":null,"errorMessage":"endpoint address must be set","messagePattern":"endpoint address must be set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/receive/config.go","lineNumber":85,"sourceCode":"\tAddress          string `json:\"address\"`\n\tCapNProtoAddress string `json:\"capnproto_address\"`\n\tAZ               string `json:\"az\"`\n}\n\nfunc (e Endpoint) String() string {\n\treturn fmt.Sprintf(\"addr: %s, capnp_addr: %s, az: %s\", e.Address, e.CapNProtoAddress, e.AZ)\n}\n\nfunc (e *Endpoint) HasAddress(addr string) bool {\n\treturn e.Address == addr || e.CapNProtoAddress == addr\n}\n\nfunc (e *Endpoint) UnmarshalJSON(data []byte) error {\n\tif err := e.unmarshal(data); err != nil {\n\t\treturn err\n\t}\n\tif e.Address == \"\" {\n\t\treturn errors.New(\"endpoint address must be set\")\n\t}\n\n\t// If the Cap'n proto address is not set, initialize it\n\t// to the existing address using the default cap'n proto server port.\n\tif e.CapNProtoAddress != \"\" {\n\t\treturn nil\n\t}\n\tif parts := strings.SplitN(e.Address, \":\", 2); len(parts) <= 2 {\n\t\te.CapNProtoAddress = parts[0] + \":\" + DefaultCapNProtoPort\n\t}\n\treturn nil\n}\n\nfunc (e *Endpoint) unmarshal(data []byte) error {\n\t// First try to unmarshal as a string.\n\terr := json.Unmarshal(data, &e.Address)\n\tif err == nil {\n\t\treturn nil","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/receive/config.go#L67-L103","documentation":"Endpoint.UnmarshalJSON validates each endpoint after unmarshaling and rejects it when the required Address field is empty. Every hashring endpoint must have an address (host:port of the receive node); this fail-fast validation prevents silently routing series to an unaddressable endpoint.","triggerScenarios":"Unmarshaling a hashring config where an endpoint object omits the `address` key or sets it to \"\" — e.g. {\"endpoints\": [{\"capnproto_address\": \"...\"}]} with no address.","commonSituations":"Template rendering with an empty variable for the address; renamed/mistyped key (`addr`, `host`) so Address stays at its zero value; partial endpoint entries added by automation.","solutions":["Add a non-empty `address` field to every endpoint in the hashring config","Check for key typos — the field must be exactly `address` (with optional `capnproto_address` additionally)","Fix the template/renderer so the address variable is always populated","Validate the full hashring JSON before applying it"],"exampleFix":"// before\n{\"endpoints\": [{\"capnproto_address\": \"recv-0:10991\"}]}\n// after\n{\"endpoints\": [{\"address\": \"recv-0:10901\", \"capnproto_address\": \"recv-0:10991\"}]}","handlingStrategy":"validation","validationCode":"func validEndpoint(e Endpoint) bool { return e.Address != \"\" }\n// before applying config:\nfor _, h := range hashrings {\n\tfor _, e := range h.Endpoints {\n\t\tif e.Address == \"\" { return errors.New(\"endpoint missing address\") }\n\t}\n}","typeGuard":null,"tryCatchPattern":"if err := json.Unmarshal(data, &cfg); err != nil {\n\tif strings.Contains(err.Error(), \"endpoint address must be set\") {\n\t\t// fix the endpoint entry and retry\n\t}\n}","preventionTips":["Always require an `address` key per endpoint in your config schema","Test-apply each endpoint object with Endpoint.UnmarshalJSON in CI","Ensure templating fails loudly when the address variable is empty"],"tags":["config","validation","hashring"],"backgroundTag":"missing-required-config-field","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}