grpc-ecosystem/grpc-gateway · error

failed to parse gRPC API Configuration from YAML in %q: %w

Error message

failed to parse gRPC API Configuration from YAML in %q: %w

What it means

loadGrpcAPIServiceFromYAML wraps yaml.Unmarshal failures when the gRPC API Configuration file is not parseable YAML at all (syntax error, tabs, malformed structure). The function first decodes to generic interface{}, so this fires before any proto validation.

Source

Thrown at internal/descriptor/grpc_api_configuration.go:17

package descriptor

import (
	"encoding/json"
	"fmt"
	"os"
	"strings"

	"github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/apiconfig"
	"go.yaml.in/yaml/v3"
	"google.golang.org/protobuf/encoding/protojson"
)

func loadGrpcAPIServiceFromYAML(yamlFileContents []byte, yamlSourceLogName string) (*apiconfig.GrpcAPIService, error) {
	var yamlContents interface{}
	if err := yaml.Unmarshal(yamlFileContents, &yamlContents); err != nil {
		return nil, fmt.Errorf("failed to parse gRPC API Configuration from YAML in %q: %w", yamlSourceLogName, err)
	}

	jsonContents, err := json.Marshal(yamlContents)
	if err != nil {
		return nil, err
	}

	// As our GrpcAPIService is incomplete, accept unknown fields.
	unmarshaler := protojson.UnmarshalOptions{
		DiscardUnknown: true,
	}

	serviceConfiguration := apiconfig.GrpcAPIService{}
	if err := unmarshaler.Unmarshal(jsonContents, &serviceConfiguration); err != nil {
		return nil, fmt.Errorf("failed to parse gRPC API Configuration from YAML in %q: %w", yamlSourceLogName, err)
	}

	return &serviceConfiguration, nil

View on GitHub (pinned to a58a4436a3)

Solutions

  1. Validate the YAML with a linter (yamllint) or by loading it in an editor with YAML syntax checking; fix indentation (spaces, not tabs)
  2. Ensure the top-level structure is a YAML mapping suitable for GrpcAPIService
  3. Confirm the file path passed to protoc --grpc-gateway_config_file points to the intended config

Example fix

// before (invalid YAML: tab indentation)
http:
	_rules:
// after
http:
  rules:
    - selector: pkg.Service.Method
      get: /v1/things
Defensive patterns

Strategy: validation

Validate before calling

// before loading config in CI
data, err := os.ReadFile(cfgPath)
if err != nil { return err }
var probe interface{}
if err := yaml.Unmarshal(data, &probe); err != nil {
    return fmt.Errorf("%s is not valid YAML: %w", cfgPath, err)
}

Try / catch

cfg, err := descriptor.LoadGrpcAPIServiceFromYAML(data, cfgPath)
if err != nil {
    if strings.Contains(err.Error(), "failed to parse gRPC API Configuration from YAML") {
        grpclog.Fatalf("fix YAML syntax in %s: %v", cfgPath, err)
    }
    return err
}

Prevention

When it happens

Trigger: Passing invalid YAML bytes to descriptor.LoadGrpcAPIServiceFromYAML (or via protoc --grpc-gateway_config_file) where yaml.Unmarshal fails — e.g. bad indentation, tabs, duplicate keys, non-mapping top-level types like a bare list or scalar.

Common situations: Hand-edited gateway YAML config with indentation/tab mistakes; config file accidentally containing JSON-incompatible or truncated content; CI pointing at the wrong file (e.g. a lockfile passed as config); tests like TestLoadGrpcAPIServiceFromYAMLRejectInvalidYAML exercising this deliberately.

Understand the failure class

Related errors


AI-assisted analysis of grpc-ecosystem/grpc-gateway@a58a4436a3 (2026-09-02). Data as JSON: /api/errors/27b26e310bd042dc. Report an issue: GitHub.