jaegertracing/jaeger · error

cannot read from index.html

Error message

cannot read from index.html: %w

What it means

loadIndexHTML fails while reading the UI's index.html after successfully opening it: io.ReadAll on the file returned an error (I/O failure mid-read). Jaeger wraps the underlying error so you can see the OS-level cause. This happens in the static handler of the jaeger-query extension when it loads embedded or on-disk UI assets at startup.

Solutions

  1. Check the wrapped OS error in the message for the real cause (permissions, path, disk).
  2. Verify the configured UI directory contains a regular, readable index.html file.
  3. Regenerate or re-download your custom UI build and retry.
  4. If using the embedded UI, ensure the binary was built correctly and submodules were initialized before building.

Example fix

// before: index.html is a directory
$ ls ui/
drwxr-xr-x  index.html/
// after: point to a real file
$ ls ui/
-rw-r--r--  index.html
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(uiDir + "/index.html")
if err != nil || info.IsDir() {
    return fmt.Errorf("invalid UI dir %s: index.html missing or not a regular file", uiDir)
}
if info.Mode().Perm()&0400 == 0 {
    return fmt.Errorf("index.html not readable")
}

Try / catch

if _, err := loadIndexHTML(dir); err != nil {
    var pathErr *fs.PathError
    if errors.As(err, &pathErr) {
        log.Fatalf("UI assets: %v at %s", pathErr.Err, pathErr.Path)
    }
    return err
}

Prevention

When it happens

Trigger: newStaticAssetsHandler calls loadIndexHTML and io.ReadAll(indexFile) returns a non-nil error after the file was opened (e.g. corrupted file, filesystem error, or a custom UI directory whose index.html is a directory/device that cannot be read).

Common situations: Pointing static_files/ui_config at a directory that lacks a valid index.html; the path resolving to a special file or a directory; disk or permission issues surfacing mid-read; corrupted custom UI build output.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01). Data as JSON: /api/errors/b89c8157075723bf. Report an issue: GitHub.

Appendix: source

Thrown at cmd/jaeger/internal/extension/jaegerquery/internal/static_handler.go:203

	out = versionPattern.ReplaceAll(out, fmt.Appendf(nil, "JAEGER_VERSION = %s;", versionJSON))
	var caps BackendCapabilities
	if h.backendCaps != nil {
		caps = h.backendCaps(ctx)
	}
	capsJSON, _ := json.Marshal(caps)
	out = capabilitiesPattern.ReplaceAll(out, fmt.Appendf(nil, "JAEGER_BACKEND_CAPABILITIES = %s;", capsJSON))
	return out
}

func loadIndexHTML(open func(string) (http.File, error)) ([]byte, error) {
	indexFile, err := open("/index.html")
	if err != nil {
		return nil, fmt.Errorf("cannot open index.html: %w", err)
	}
	defer indexFile.Close()
	indexBytes, err := io.ReadAll(indexFile)
	if err != nil {
		return nil, fmt.Errorf("cannot read from index.html: %w", err)
	}
	return indexBytes, nil
}

func loadUIConfig(uiConfig string) (*loadedConfig, error) {
	if uiConfig == "" {
		return nil, nil
	}
	bytesConfig, err := os.ReadFile(filepath.Clean(uiConfig))
	if err != nil {
		return nil, fmt.Errorf("cannot read UI config file %v: %w", uiConfig, err)
	}
	var r []byte

	ext := filepath.Ext(uiConfig)
	switch strings.ToLower(ext) {
	case ".json":
		var c map[string]any

View on GitHub (pinned to 806f444784)