Each entry below describes one symptom, its cause and the action that resolves it. The commands assume the release code in the namespace code.
Install fails on a value check
helm upgrade exits before creating any object, and the output ends with a message from the chart’s value checks.
Cause. The values contradict each other or miss a required field. The chart checks them first and prints every finding at once.
Action. Change the values the message names and run the command again. The messages and their fixes:
| Message | Fix |
|---|---|
is not bundled with Deckhouse Code | Remove install: true or enabled: true from the subchart the message names, or installCertmanager: true, and provide the component in the cluster; see Components the cluster provides. |
Registry storage secret is required | Fill global.codeHelm.externalSecrets.registry.storage.s3, name an existing Secret in registry.storage.secret, or set registry.enabled: false. |
global.codeHelm.externalSecrets.registryDockerConfig is required | Put the Base64-encoded .dockerconfigjson of the image registry into global.codeHelm.externalSecrets.registryDockerConfig. |
Backup object storage is not configured | Fill global.codeHelm.externalSecrets.backup with the access keys of the backup storage, or name an existing s3cmd configuration Secret in gitlab.toolbox.backups.objectStorage.config.secret. |
praefectPassword is set but global.praefect.psql.host is empty | Set global.praefect.psql.host, user and dbName to the Praefect database. |
redisSentinelPassword is set but global.redis.sentinelAuth.enabled is false | Set global.redis.sentinelAuth.enabled: true and list the Sentinel servers in global.redis.sentinels, or remove global.codeHelm.externalSecrets.redisSentinelPassword. |
Two sources for the Redis Sentinel password | Remove global.redis.sentinelAuth.secret and key so that the chart creates the Secret, or remove global.codeHelm.externalSecrets.redisSentinelPassword and keep the existing Secret. |
global.codeHelm.externalSecrets.s3.<field> is required | Fill every field of the s3 block: provider, region, endpoint, aws_access_key_id and aws_secret_access_key. |
codeHelm.ingress.tls.mode=certManager requires cert-manager | Install cert-manager, or switch global.codeHelm.ingress.tls.mode to manual and supply the certificates as Secrets. |
codeHelm.ingress.tls.mode=manual: no TLS secret name configured | Set global.ingress.tls.secretName, or gitlab.webservice.ingress.tls.secretName together with the ingress.tls.secretName of the other enabled components. |
generates Certificate resources with fixed secret names, but the following overrides were found | Remove the ingress.tls.secretName overrides, or switch to the manual TLS mode. |
Only the default internal ClusterIP shell Service is compatible with the loadbalancer | Set gitlab.gitlab-shell.service.type back to ClusterIP, or disable the load balancer with global.codeHelm.loadbalancer.enabled: false. |
Istio service mesh and internal TLS are mutually exclusive | With Istio, set global.codeHelm.tls.internal.enabled, global.gitaly.tls.enabled, global.praefect.tls.enabled, global.workhorse.tls.enabled, gitlab.webservice.tls.enabled and, when the registry is enabled, registry.tls.enabled to false. |
the following upstream TLS flags must also be enabled | Set the flags the message lists back to true, or disable the internal TLS with global.codeHelm.tls.internal.enabled: false. |
kubeRbacProxy.enabled=true requires caSecret or clusterIssuer | Set global.codeHelm.kubeRbacProxy.clusterIssuer to an existing ClusterIssuer, or caSecret to a Secret with the key ca.crt. |
kubeRbacProxy.enabled=true requires kubeRbacProxy.serviceAccountToken | Put the bearer token of the Prometheus ServiceAccount into global.codeHelm.kubeRbacProxy.serviceAccountToken. |
Load balancer Service has no external address
d8 k -n code get service code-code-loadbalancer shows <pending> in the EXTERNAL-IP column.
Cause. The cluster has no implementation that assigns addresses to Services of type LoadBalancer, or the implementation needs an annotation to pick the address.
Action. Read the Service events:
d8 k -n code describe service code-code-loadbalancerAdd the annotation the implementation expects to global.codeHelm.loadbalancer.annotations, for example metallb.universe.tf/loadBalancerIPs for MetalLB. When the cluster has no such implementation, disable the load balancer with global.codeHelm.loadbalancer.enabled: false, point DNS at the ingress controller and expose SSH with gitlab.gitlab-shell.service.type: NodePort.
Pods stay in ImagePullBackOff
d8 k -n code get pods shows pods in the ImagePullBackOff or ErrImagePull state.
Cause. The image pull Secret code-image-pull-secret, built from global.codeHelm.externalSecrets.registryDockerConfig, holds wrong or expired credentials, or the nodes cannot reach the image registry.
Action. Read the pull error from the pod events:
d8 k -n code describe pod <POD_NAME>An unauthorized response points to the credentials: encode the .dockerconfigjson again with base64 -w0 and upgrade the release. A connection error points to the network path from the nodes to the registry.
Pods stay in Pending
d8 k -n code get pods shows the Gitaly or Praefect pods in the Pending state.
Cause. No StorageClass satisfies gitlab.gitaly.persistence.storageClass, the cluster has no default StorageClass, or no node has enough CPU and memory for the pod’s requests.
Action. Read the pod events:
d8 k -n code describe pod <POD_NAME>A FailedScheduling event that names a PersistentVolumeClaim points to the StorageClass; list the classes with d8 k get storageclass. An event that names CPU or memory points to the node resources.
Certificate is not issued
d8 k -n code get certificate shows False in the READY column for code-tls, code-registry-tls or code-pages-tls, and the browser reports an invalid certificate.
Cause. The ClusterIssuer from global.codeHelm.ingress.tls.clusterIssuer does not exist, or the issuer cannot complete the challenge because the DNS name does not resolve to the load balancer yet.
Action. Read the Certificate status and the issuer:
d8 k -n code describe certificate code-tls
d8 k get clusterissuerCreate the ClusterIssuer or name an existing one, and confirm that the DNS records point at the load balancer address. cert-manager retries the issuance on its own once the cause is removed.
Migrations job fails
d8 k -n code get jobs shows the job code-migrations-<suffix> with 0/1 completions, and the web service and Sidekiq pods wait for it.
Cause. PostgreSQL is not reachable at global.psql.host, the password in global.codeHelm.externalSecrets.psqlPassword or in the Secret from global.psql.password.secret is wrong, the role has no rights on the database, or the release skipped a Deckhouse Code version a later migration depends on.
Action. Read the job log:
d8 k -n code logs job/code-migrations-<suffix>Resolve the connection or the credentials first. When the log names a missing earlier migration, follow the version order in Upgrade.
Praefect pods restart
The code-praefect pods restart, and their logs report a failed connection to PostgreSQL.
Cause. The Praefect database in global.praefect.psql.host, dbName and user does not exist or the password from global.codeHelm.externalSecrets.praefectPassword is wrong. Praefect has its own database and does not use the application one.
Action. Read the pod log:
d8 k -n code logs statefulset/code-praefectCreate the database and the role on the PostgreSQL server, set the password and upgrade the release.
Object storage rejects requests
Uploads and CI/CD artifacts fail, and the web service or Sidekiq logs show an AccessDenied or NoSuchBucket response from the storage.
Cause. The connection in global.codeHelm.externalSecrets.s3 or in the Secret from global.appConfig.object_store.connection.secret holds a wrong endpoint, region or key, or a bucket from global.appConfig.<store>.bucket does not exist.
Action. Compare the connection with the storage console and confirm that every bucket from Requirements exists and the keys have write access to it. For a storage that addresses buckets in the URL path, add path_style: true to the connection.
Helm upgrade times out
helm upgrade exits with Error: UPGRADE FAILED: timed out waiting for the condition.
Cause. A pod or the migrations job did not become ready within the wait time of Helm, for one of the causes above.
Action. Inspect the pods and jobs of the release:
d8 k -n code get pods,jobsResolve the cause, then run helm upgrade again; add --timeout when the release needs more time than the default.