go-kratos/kratos · error
ErrorCode: %d
Error message
ErrorCode: %d
What it means
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.
Source
Thrown at contrib/registry/discovery/impl_registrar.go:110
} else {
p.Set(_paramKeyStatus, strconv.FormatInt(ins.Status, 10))
}
p.Set(_paramKeyMetadata, string(metadata))
// send request to Discovery server.
if _, err = d.httpClient.R().
SetContext(ctx).
SetQueryParamsFromValues(p).
SetResult(&res).
Post(uri); err != nil {
d.switchNode()
log.Error("Discovery: register client.Get failed",
"uri", uri+"?"+p.Encode(), "zone", c.Zone, "env", c.Env, "appid", ins.AppID, "addrs", ins.Addrs, "error", err)
return
}
if res.Code != 0 {
err = fmt.Errorf("ErrorCode: %d", res.Code)
log.Error("Discovery: register client.Get returned code",
"uri", uri, "env", c.Env, "appid", ins.AppID, "addrs", ins.Addrs, "code", res.Code)
}
log.Info("Discovery: register client.Get succeeded", "uri", uri, "env", c.Env, "appid", ins.AppID, "addrs", ins.Addrs)
return
}
func (d *Discovery) Deregister(_ context.Context, service *registry.ServiceInstance) error {
ins := fromServerInstance(service, d.config)
return d.cancel(ins)
}
View on GitHub (pinned to 668db92c2c)
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
Example fix
// before: appid with invalid format gets rejected with ErrorCode: -400
cfg := discovery.WithAppID("My App")
// after: appid must match the server's naming rules
cfg := discovery.WithAppID("my.app.service") Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate the instance shape before registering
func validInstance(ins *registry.ServiceInstance) error {
if ins.Name == "" || len(ins.Endpoints) == 0 {
return fmt.Errorf("invalid instance: name and endpoints required")
}
for _, ep := range ins.Endpoints {
if u, err := url.Parse(ep); err != nil || u.Host == "" {
return fmt.Errorf("invalid endpoint %q", ep)
}
}
return nil
} Try / catch
err := registrar.Register(ctx, ins)
if err != nil {
if strings.HasPrefix(err.Error(), "ErrorCode:") {
// business rejection from the discovery server: log code, do NOT blind-retry the same payload
log.Error("discovery rejected registration", "err", err, "appid", ins.Name)
return err
}
// transport error: the client already switched nodes; a later retry is safe
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- RegisterInstance err %v,%v
- response Error %d
- retry after %d times
- unsupported key: %s format: %s
- invalid path: %q is not a message
AI-assisted analysis of go-kratos/kratos@668db92c2c (2026-08-16).
Data as JSON: /api/errors/11a8f5378849b67a.
Report an issue: GitHub.