{"record":{"id":"d8d3e7230d372bc3","repo":"jaegertracing/jaeger","slug":"failed-to-check-if-alias-exists-w","errorCode":null,"errorMessage":"failed to check if alias exists: %w","messagePattern":"failed to check if alias exists: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/elasticsearch/esclient/index_client.go","lineNumber":225,"sourceCode":"\t\treturn fmt.Errorf(\"failed to delete aliases: %w\", err)\n\t}\n\treturn nil\n}\n\n// AliasExists check whether an alias exists or not\nfunc (i *IndicesClient) AliasExists(ctx context.Context, alias string) (bool, error) {\n\t_, err := i.request(ctx, elasticRequest{\n\t\tendpoint: \"_alias/\" + alias,\n\t\tmethod:   http.MethodHead,\n\t})\n\tif err != nil {\n\t\tvar responseError ResponseError\n\t\tif errors.As(err, &responseError) {\n\t\t\tif responseError.StatusCode == http.StatusNotFound {\n\t\t\t\treturn false, nil\n\t\t\t}\n\t\t}\n\t\treturn false, fmt.Errorf(\"failed to check if alias exists: %w\", err)\n\t}\n\treturn true, nil\n}\n\n// IndexExists check whether an index exists or not\nfunc (i *IndicesClient) IndexExists(ctx context.Context, index string) (bool, error) {\n\t_, err := i.request(ctx, elasticRequest{\n\t\tendpoint: index,\n\t\tmethod:   http.MethodHead,\n\t})\n\tif err != nil {\n\t\tvar responseError ResponseError\n\t\tif errors.As(err, &responseError) {\n\t\t\tif responseError.StatusCode == http.StatusNotFound {\n\t\t\t\treturn false, nil\n\t\t\t}\n\t\t}\n\t\treturn false, fmt.Errorf(\"failed to check if index exists: %w\", err)","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/internal/storage/elasticsearch/esclient/index_client.go#L207-L243","documentation":"Returned by IndicesClient.AliasExists when the HEAD /_alias/<name> probe fails with anything other than a 404 ResponseError. A 404 is translated to (false, nil); every other failure (transport error, 4xx/5xx not surfaced as ResponseError, timeout) becomes this wrapped error. It means the alias-existence check itself failed, not that the alias is missing.","triggerScenarios":"HEAD _alias/<alias> fails without a 404 ResponseError: connection refused, TLS failure, timeout, or a non-404 structured error not wrapped as ResponseError (e.g. 401/403, 503).","commonSituations":"ES credentials missing/invalid so the HEAD returns 401; ES temporarily unavailable during Jaeger startup before it decides to create the alias; load balancer returning 503 HTML bodies that can't be parsed as ResponseError.","solutions":["Check ES connectivity and auth (401/403 indicate bad credentials) via curl","Distinguish from a clean 'alias does not exist' (which returns false, nil) before deciding to create the alias","Retry after verifying cluster health — this check is read-only and safe to repeat","Unwrap the error to inspect the underlying cause (timeout vs auth vs connection)"],"exampleFix":"// before\nexists, err := client.AliasExists(ctx, \"jaeger-span-write\")\nif err != nil { return err } // cannot tell missing vs broken\n// after\nexists, err := client.AliasExists(ctx, \"jaeger-span-write\")\nif err != nil {\n    var respErr esclient.ResponseError\n    if errors.As(err, &respErr) && respErr.StatusCode == 401 {\n        return fmt.Errorf(\"check ES credentials: %w\", err)\n    }\n    return retryable(err)\n}","handlingStrategy":"try-catch","validationCode":"// pre-flight auth check\nresp, err := http.Get(esURL + \"/_cluster/health\")\nif err != nil || resp.StatusCode == 401 {\n    return fmt.Errorf(\"bad ES credentials\")\n}","typeGuard":"var respErr esclient.ResponseError\nisAuthProblem := func(err error) bool {\n    var re esclient.ResponseError\n    return errors.As(err, &re) && (re.StatusCode == 401 || re.StatusCode == 403)\n}","tryCatchPattern":"exists, err := client.AliasExists(ctx, alias)\nif err != nil {\n    var respErr esclient.ResponseError\n    if errors.As(err, &respErr) {\n        return fmt.Errorf(\"alias probe rejected, status=%d\", respErr.StatusCode)\n    }\n    return retryable(err) // transport failure: do NOT treat as 'alias missing'\n}","preventionTips":["Never treat an error from AliasExists as 'alias does not exist' — only (false, nil) means that","Validate ES credentials at startup (401/403 surface here)","Retry existence probes; they are read-only"],"tags":["elasticsearch","auth","aliases"],"backgroundTag":"elasticsearch-request-failed","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}