netbirdio/netbird · critical
unexpected config protocol type %v
Error message
unexpected config protocol type %v
What it means
A panic raised by ToResponseProto in management/internals/shared/grpc/conversion.go:277 when the management server's configured signal protocol (nbconfig.Protocol) is not one of the mapped values UDP, DTLS, HTTP, HTTPS, TCP. It exists to catch config/proto drift at runtime; an unmapped value crashes the request path instead of silently sending a wrong protocol to the agent.
Source
Thrown at management/internals/shared/grpc/conversion.go:277
}
return precomputedDeprecatedRemotePeersConstraint.Check(peerNBVersion)
}
func ToResponseProto(configProto nbconfig.Protocol) proto.HostConfig_Protocol {
switch configProto {
case nbconfig.UDP:
return proto.HostConfig_UDP
case nbconfig.DTLS:
return proto.HostConfig_DTLS
case nbconfig.HTTP:
return proto.HostConfig_HTTP
case nbconfig.HTTPS:
return proto.HostConfig_HTTPS
case nbconfig.TCP:
return proto.HostConfig_TCP
default:
panic(fmt.Errorf("unexpected config protocol type %v", configProto))
}
}
// buildJWTConfig constructs JWT configuration for SSH servers from management server config
func buildJWTConfig(config *nbconfig.HttpServerConfig, deviceFlowConfig *nbconfig.DeviceAuthorizationFlow) *proto.JWTConfig {
if config == nil || config.AuthAudience == "" {
return nil
}
issuer := strings.TrimSpace(config.AuthIssuer)
if issuer == "" && deviceFlowConfig != nil {
if d := deriveIssuerFromTokenEndpoint(deviceFlowConfig.ProviderConfig.TokenEndpoint); d != "" {
issuer = d
}
}
if issuer == "" {
return nil
}View on GitHub (pinned to 93e97f4bf1)
Solutions
- Check which nbconfig.Protocol value reached the switch (the panic message prints it with %v) and add a matching proto.HostConfig_* case or map it deliberately.
- Ensure the management signal configuration (signal protocol settings) uses one of the supported values UDP/DTLS/HTTP/HTTPS/TCP.
- Redeploy management from a consistent build so config parsing and conversion share the same protocol set.
Example fix
// before
default:
panic(fmt.Errorf("unexpected config protocol type %v", configProto))
// after: handle the new constant instead of panicking
case nbconfig.QUIC:
return proto.HostConfig_QUIC
default:
panic(fmt.Errorf("unexpected config protocol type %v", configProto)) Defensive patterns
Strategy: validation
Validate before calling
// Go: guard config before calling into the conversion path
func isSupportedProtocol(p nbconfig.Protocol) bool {
switch p {
case nbconfig.UDP, nbconfig.DTLS, nbconfig.HTTP, nbconfig.HTTPS, nbconfig.TCP:
return true
}
return false
}
if !isSupportedProtocol(cfg.Protocol) {
return fmt.Errorf("unsupported signal protocol: %v", cfg.Protocol)
} Try / catch
// Go: keep the panic from killing the whole process at API boundaries
// (the panic is intentional fail-fast; recovery is for supervisors)
defer func() {
if r := recover(); r != nil {
log.Errorf("conversion panic: %v", r)
err = fmt.Errorf("protocol conversion failed")
}
}()
resp, err = convert(configProto) Prevention
- When adding a nbconfig protocol constant, update ToResponseProto in the same change and add a test enumerating all constants.
- Run a conversion unit test over every valid nbconfig.Protocol value in CI so an unmapped value fails the build, not production.
- Avoid hand-editing persisted management config that feeds this switch.
When it happens
Trigger: Management receives a Sync/Login flow whose host config carries a Protocol value outside the known set — typically a newly introduced nbconfig constant that was never added to this switch, or a hand-edited/back-incompatible management config.
Common situations: Running a management build where nbconfig gained a new protocol constant (version skew between config parsing and this conversion); development branches adding a transport without updating the switch; corrupt or unusual signal configuration data.
Related errors
- management client is not initialised
- job not implemented
- service name is required
- service name exceeds maximum length of 255 characters
- at least one target is required
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/1ae1e27484467045.
Report an issue: GitHub.