{"record":{"id":"29e950f007d6003e","repo":"weaviate/weaviate","slug":"init-context-expired-before-remote-was-ready-29e950","errorCode":null,"errorMessage":"init context expired before remote was ready","messagePattern":"init context expired before remote was ready","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/multi2vec-bind/clients/startup.go","lineNumber":40,"sourceCode":"func (v *vectorizer) WaitForStartup(initCtx context.Context,\n\tinterval time.Duration,\n) error {\n\tt := time.NewTicker(interval)\n\tdefer t.Stop()\n\texpired := initCtx.Done()\n\tvar lastErr error\n\tfor {\n\t\tselect {\n\t\tcase <-t.C:\n\t\t\tlastErr = v.checkReady(initCtx)\n\t\t\tif lastErr == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tv.logger.\n\t\t\t\tWithField(\"action\", \"multi2vec_remote_wait_for_startup\").\n\t\t\t\tWithError(lastErr).Warnf(\"multi2vec-bind inference service not ready\")\n\t\tcase <-expired:\n\t\t\treturn errors.Wrapf(lastErr, \"init context expired before remote was ready\")\n\t\t}\n\t}\n}\n\nfunc (v *vectorizer) checkReady(initCtx context.Context) error {\n\t// spawn a new context (derived on the overall context) which is used to\n\t// consider an individual request timed out\n\trequestCtx, cancel := context.WithTimeout(initCtx, 500*time.Millisecond)\n\tdefer cancel()\n\n\treq, err := http.NewRequestWithContext(requestCtx, http.MethodGet,\n\t\tv.url(\"/.well-known/ready\"), nil)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"create check ready request\")\n\t}\n\n\tres, err := v.httpClient.Do(req)\n\tif err != nil {","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/modules/multi2vec-bind/clients/startup.go#L22-L58","documentation":"WaitForStartup polls the inference service's /.well-known/ready endpoint every `interval` until the init context expires. If every checkReady attempt failed until initCtx is done, it wraps the last observed error as 'init context expired before remote was ready'. This is Weaviate's startup gating failing because the remote inference service never became healthy in time.","triggerScenarios":"Calling WaitForStartup(initCtx, interval) when the multi2vec-bind container is absent, still downloading model weights, crashed, or reachable only after initCtx's deadline; lastErr may be a connection refused, timeout, or 'not ready: status N' error.","commonSituations":"First boot with large multi-modal models still downloading inside the container, exceeding the init timeout; inference container crashed on startup; wrong INFERENCE_ORIGIN so readiness is never reachable; too-short init context in tests.","solutions":["Start/repair the multi2vec-bind inference container and confirm /.well-known/ready returns 200 with curl","Give the container more time — large models may take minutes to load; increase the init context deadline","Check the lastErr (wrapped inside) in the log to see the underlying cause: connection refused vs HTTP status vs timeout","Fix INFERENCE_ORIGIN if it points to the wrong host/port","Check inference container logs for startup errors (OOM, missing model, image incompatibility)"],"exampleFix":"// before\ninitCtx, cancel := context.WithTimeout(context.Background(), 60*time.Second) // too short for model download\nerr := client.WaitForStartup(initCtx, 500*time.Millisecond)\n// after\ninitCtx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) // allow model loading\nerr := client.WaitForStartup(initCtx, 500*time.Millisecond)","handlingStrategy":"retry","validationCode":"ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) // generous for model loading\ndefer cancel()\nfor {\n\tresp, err := http.Get(origin + \"/.well-known/ready\")\n\tif err == nil && resp.StatusCode == http.StatusOK {\n\t\tresp.Body.Close()\n\t\tbreak\n\t}\n\tif resp != nil { resp.Body.Close() }\n\ttime.Sleep(5 * time.Second)\n}","typeGuard":null,"tryCatchPattern":"if err := client.WaitForStartup(initCtx, time.Second); err != nil {\n\tif strings.Contains(err.Error(), \"init context expired before remote was ready\") {\n\t\t// unwrap lastErr: distinguish connection refused vs status; log inference container state\n\t\tlog.Errorf(\"multi2vec-bind never became ready: %v\", err)\n\t}\n\treturn err\n}","preventionTips":["Use docker-compose depends_on/healthcheck or K8s init containers to order startup","Allow long init deadlines — first boot downloads and loads large multi-modal models","Monitor inference container logs and memory to catch crash loops early","Verify INFERENCE_ORIGIN before startup, not during it"],"tags":["startup","readiness","timeout","inference-service","module"],"backgroundTag":"service-startup-timeout","analyzedSha":"75aa4b6d11f8818305aafd4440b4e32794f7ca04","analyzedAt":"2026-09-04T14:58:20.392Z","contentChangedAt":"2026-09-04T14:58:20.392Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}