{"record":{"id":"11a8f5378849b67a","repo":"go-kratos/kratos","slug":"errorcode-d-11a8f5","errorCode":null,"errorMessage":"ErrorCode: %d","messagePattern":"ErrorCode: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"contrib/registry/discovery/impl_registrar.go","lineNumber":110,"sourceCode":"\t} else {\n\t\tp.Set(_paramKeyStatus, strconv.FormatInt(ins.Status, 10))\n\t}\n\tp.Set(_paramKeyMetadata, string(metadata))\n\n\t// send request to Discovery server.\n\tif _, err = d.httpClient.R().\n\t\tSetContext(ctx).\n\t\tSetQueryParamsFromValues(p).\n\t\tSetResult(&res).\n\t\tPost(uri); err != nil {\n\t\td.switchNode()\n\t\tlog.Error(\"Discovery: register client.Get failed\",\n\t\t\t\"uri\", uri+\"?\"+p.Encode(), \"zone\", c.Zone, \"env\", c.Env, \"appid\", ins.AppID, \"addrs\", ins.Addrs, \"error\", err)\n\t\treturn\n\t}\n\n\tif res.Code != 0 {\n\t\terr = fmt.Errorf(\"ErrorCode: %d\", res.Code)\n\t\tlog.Error(\"Discovery: register client.Get returned code\",\n\t\t\t\"uri\", uri, \"env\", c.Env, \"appid\", ins.AppID, \"addrs\", ins.Addrs, \"code\", res.Code)\n\t}\n\n\tlog.Info(\"Discovery: register client.Get succeeded\", \"uri\", uri, \"env\", c.Env, \"appid\", ins.AppID, \"addrs\", ins.Addrs)\n\n\treturn\n}\n\nfunc (d *Discovery) Deregister(_ context.Context, service *registry.ServiceInstance) error {\n\tins := fromServerInstance(service, d.config)\n\treturn d.cancel(ins)\n}\n","sourceCodeStart":92,"sourceCodeEnd":124,"githubUrl":"https://github.com/go-kratos/kratos/blob/668db92c2c001e9552594ba5a8aede8456af6d7e/contrib/registry/discovery/impl_registrar.go#L92-L124","documentation":"Thrown by Kratos' Bilibili Discovery registrar after the HTTP POST to the discovery server's /discovery/register endpoint succeeds at the transport layer, but the JSON response body carries a non-zero business code (res.Code != 0). The discovery server uses this code field to signal rejection of the registration (e.g. invalid appid/env, duplicate or conflicting instance registration). The wrapped value is only the numeric code; the server's message string is logged but not returned.","triggerScenarios":"Calling registrar.Register()/registry.Register() with a Discovery instance: config env/zone values the server does not recognize, an AppID that is not provisioned on the discovery server, addrs that fail server-side validation, or re-registering an instance with conflicting metadata/status. The HTTP call itself must succeed (otherwise the resty error path at impl_registrar.go:98 is taken instead); only the parsed {code,message} body with code != 0 produces this error.","commonSituations":"Misconfigured KRATOS_DISCOVERY env/zone/appid in deployment config; pointing the registrar at a discovery cluster that does not know the appid; registering the same appid+addrs from a second environment causing a conflict code; discovery server version differences that return different rejection codes than the client expects.","solutions":["Check the registrar log line 'Discovery: register client.Get returned code' for the uri/appid/code, and map that code against the Bilibili discovery server's code table (e.g. -304/-404 style codes) to see why registration was rejected","Verify the Discovery config (env, zone, appid, addrs) matches what is provisioned on the discovery server; appid naming rules and env values are strict","Confirm the addrs you register are reachable from the discovery server's health checks and correctly formatted (scheme://host:port)","If the server rejects due to stale state, deregister the old instance (or let its lease expire) and retry registration","If the code is unknown, curl the register URL from the logged uri+params directly and inspect the full {code,message} body for the exact reason"],"exampleFix":"// before: appid with invalid format gets rejected with ErrorCode: -400\ncfg := discovery.WithAppID(\"My App\")\n\n// after: appid must match the server's naming rules\ncfg := discovery.WithAppID(\"my.app.service\")","handlingStrategy":"try-catch","validationCode":"// Pre-validate the instance shape before registering\nfunc validInstance(ins *registry.ServiceInstance) error {\n\tif ins.Name == \"\" || len(ins.Endpoints) == 0 {\n\t\treturn fmt.Errorf(\"invalid instance: name and endpoints required\")\n\t}\n\tfor _, ep := range ins.Endpoints {\n\t\tif u, err := url.Parse(ep); err != nil || u.Host == \"\" {\n\t\t\treturn fmt.Errorf(\"invalid endpoint %q\", ep)\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"err := registrar.Register(ctx, ins)\nif err != nil {\n\tif strings.HasPrefix(err.Error(), \"ErrorCode:\") {\n\t\t// business rejection from the discovery server: log code, do NOT blind-retry the same payload\n\t\tlog.Error(\"discovery rejected registration\", \"err\", err, \"appid\", ins.Name)\n\t\treturn err\n\t}\n\t// transport error: the client already switched nodes; a later retry is safe\n}","preventionTips":["Provision the appid on the discovery server before deploying the service","Keep env/zone config identical across all replicas so registrations do not conflict","Monitor the 'register client.Get returned code' log line and alert on non-zero codes","Deregister cleanly on shutdown so stale instances do not cause conflict codes on restart"],"tags":["go","kratos","service-registry","discovery","registration"],"backgroundTag":null,"analyzedSha":"668db92c2c001e9552594ba5a8aede8456af6d7e","analyzedAt":"2026-08-16T02:07:20.704Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}