openimsdk/open-im-server · error

failed to create in-cluster config: %v

Error message

failed to create in-cluster config: %v

What it means

NewKubernetesConnManager builds service discovery on in-cluster Kubernetes credentials via rest.InClusterConfig(), which requires the pod's service account token and ca.crt mounted at /var/run/secrets/kubernetes.io/serviceaccount/. When those are absent or unreadable (i.e. not running inside a K8s cluster), it fails and the error is wrapped as 'failed to create in-cluster config: %v'.

Source

Thrown at pkg/common/discovery/kubernetes/kubernetes.go:37

)

type KubernetesConnManager struct {
	clientset   *kubernetes.Clientset
	namespace   string
	dialOptions []grpc.DialOption

	rpcTargets map[string]string
	selfTarget string

	mu      sync.RWMutex
	connMap map[string][]*grpc.ClientConn
}

// NewKubernetesConnManager creates a new connection manager that uses Kubernetes services for service discovery.
func NewKubernetesConnManager(namespace string, options ...grpc.DialOption) (*KubernetesConnManager, error) {
	config, err := rest.InClusterConfig()
	if err != nil {
		return nil, fmt.Errorf("failed to create in-cluster config: %v", err)
	}

	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		return nil, fmt.Errorf("failed to create clientset: %v", err)
	}

	k := &KubernetesConnManager{
		clientset:   clientset,
		namespace:   namespace,
		dialOptions: options,
		connMap:     make(map[string][]*grpc.ClientConn),
	}

	go k.watchEndpoints()

	return k, nil
}

View on GitHub (pinned to 175a7bb067)

Solutions

  1. Use a discovery config suited to your environment (e.g. the direct/etcd/zookeeper discovery) when not running in Kubernetes
  2. Set automountServiceAccountToken: true (or a serviceAccountName) on the pod spec so the token is mounted
  3. Verify /var/run/secrets/kubernetes.io/serviceaccount/token and ca.crt exist inside the pod
  4. Ensure the underlying rest error (shown in %v) is fixed — e.g. missing KUBERNETES_SERVICE_HOST env means you're not in-cluster

Example fix

// before (pod spec)
spec: { automountServiceAccountToken: false }
// after
spec:
  serviceAccountName: openim-sa
  automountServiceAccountToken: true
Defensive patterns

Strategy: fallback

Validate before calling

func inCluster() bool {
	if os.Getenv("KUBERNETES_SERVICE_HOST") == "" { return false }
	_, err := os.Stat("/var/run/secrets/kubernetes.io/serviceaccount/token")
	return err == nil
}
// choose kubernetes discovery only if inCluster()

Try / catch

mgr, err := discovery.NewKubernetesConnManager(ns, opts...)
if err != nil && strings.Contains(err.Error(), "failed to create in-cluster config") {
	log.ZWarn(ctx, "not in kubernetes, falling back to direct discovery", err)
	mgr, err = discovery.NewDirectConnManager(opts...)
}
if err != nil { return err }

Prevention

When it happens

Trigger: Calling NewKubernetesConnManager from a binary running outside a Kubernetes pod (local dev, docker without K8s mounts), or a pod whose service account token volume isn't mounted / RBAC disabled token projection.

Common situations: Running openim locally while the kubernetes discovery module is selected in config; K8s pod started without a service account or with automountServiceAccountToken: false; very old clusters lacking projected service account tokens.

Related errors


AI-assisted analysis of openimsdk/open-im-server@175a7bb067 (2026-09-04). Data as JSON: /api/errors/4c985b3c6193a2b4. Report an issue: GitHub.