{"record":{"id":"1ae1e27484467045","repo":"netbirdio/netbird","slug":"unexpected-config-protocol-type-v","errorCode":null,"errorMessage":"unexpected config protocol type %v","messagePattern":"unexpected config protocol type (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"management/internals/shared/grpc/conversion.go","lineNumber":277,"sourceCode":"\t}\n\n\treturn precomputedDeprecatedRemotePeersConstraint.Check(peerNBVersion)\n}\n\nfunc ToResponseProto(configProto nbconfig.Protocol) proto.HostConfig_Protocol {\n\tswitch configProto {\n\tcase nbconfig.UDP:\n\t\treturn proto.HostConfig_UDP\n\tcase nbconfig.DTLS:\n\t\treturn proto.HostConfig_DTLS\n\tcase nbconfig.HTTP:\n\t\treturn proto.HostConfig_HTTP\n\tcase nbconfig.HTTPS:\n\t\treturn proto.HostConfig_HTTPS\n\tcase nbconfig.TCP:\n\t\treturn proto.HostConfig_TCP\n\tdefault:\n\t\tpanic(fmt.Errorf(\"unexpected config protocol type %v\", configProto))\n\t}\n}\n\n// buildJWTConfig constructs JWT configuration for SSH servers from management server config\nfunc buildJWTConfig(config *nbconfig.HttpServerConfig, deviceFlowConfig *nbconfig.DeviceAuthorizationFlow) *proto.JWTConfig {\n\tif config == nil || config.AuthAudience == \"\" {\n\t\treturn nil\n\t}\n\n\tissuer := strings.TrimSpace(config.AuthIssuer)\n\tif issuer == \"\" && deviceFlowConfig != nil {\n\t\tif d := deriveIssuerFromTokenEndpoint(deviceFlowConfig.ProviderConfig.TokenEndpoint); d != \"\" {\n\t\t\tissuer = d\n\t\t}\n\t}\n\tif issuer == \"\" {\n\t\treturn nil\n\t}","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/management/internals/shared/grpc/conversion.go#L259-L295","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ndefault:\n    panic(fmt.Errorf(\"unexpected config protocol type %v\", configProto))\n\n// after: handle the new constant instead of panicking\ncase nbconfig.QUIC:\n    return proto.HostConfig_QUIC\ndefault:\n    panic(fmt.Errorf(\"unexpected config protocol type %v\", configProto))","handlingStrategy":"validation","validationCode":"// Go: guard config before calling into the conversion path\nfunc isSupportedProtocol(p nbconfig.Protocol) bool {\n    switch p {\n    case nbconfig.UDP, nbconfig.DTLS, nbconfig.HTTP, nbconfig.HTTPS, nbconfig.TCP:\n        return true\n    }\n    return false\n}\n\nif !isSupportedProtocol(cfg.Protocol) {\n    return fmt.Errorf(\"unsupported signal protocol: %v\", cfg.Protocol)\n}","typeGuard":null,"tryCatchPattern":"// Go: keep the panic from killing the whole process at API boundaries\n// (the panic is intentional fail-fast; recovery is for supervisors)\ndefer func() {\n    if r := recover(); r != nil {\n        log.Errorf(\"conversion panic: %v\", r)\n        err = fmt.Errorf(\"protocol conversion failed\")\n    }\n}()\nresp, err = convert(configProto)","preventionTips":["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."],"tags":["go","netbird","panic","grpc","protocol-mapping","management","config"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}