# Default Content Encoding Formats in Kratos and How to Add Custom Codecs

> Explore Kratos default content encoding formats JSON Proto YAML XML Form and learn how to add custom codecs by implementing the Codec interface in Go

- Repository: [Kratos/kratos](https://github.com/go-kratos/kratos)
- Tags: how-to-guide
- Published: 2026-03-02

---

**Kratos ships with five built-in content encoding formats (JSON, Proto, YAML, XML, and Form) and provides a global registry in [`encoding/encoding.go`](https://github.com/go-kratos/kratos/blob/main/encoding/encoding.go) that allows developers to register custom codecs by implementing the `Codec` interface and calling `encoding.RegisterCodec()` in an `init` function.**

The `go-kratos/kratos` framework provides a flexible, extensible codec system for HTTP and gRPC transports that maps content subtypes to serialization implementations. Understanding the default content encoding formats supported by Kratos and the registration mechanism enables seamless integration of custom data formats without modifying core library code.

## Built-in Content Encoding Formats in Kratos

Kratos registers the following codecs automatically on startup in the global registry located in [`encoding/encoding.go`](https://github.com/go-kratos/kratos/blob/main/encoding/encoding.go):

- **JSON** (`json`): Located in [`encoding/json/json.go`](https://github.com/go-kratos/kratos/blob/main/encoding/json/json.go). Uses `protojson` for protobuf messages and falls back to the standard `encoding/json` package for other types. This serves as the default fallback when no specific content type is specified.
- **Proto** (`proto`): Located in [`encoding/proto/proto.go`](https://github.com/go-kratos/kratos/blob/main/encoding/proto/proto.go). The default codec for gRPC transports, handling raw protobuf message marshaling and unmarshaling.
- **YAML** (`yaml`): Located in [`encoding/yaml/yaml.go`](https://github.com/go-kratos/kratos/blob/main/encoding/yaml/yaml.go). Implements serialization via `gopkg.in/yaml.v3`.
- **XML** (`xml`): Located in [`encoding/xml/xml.go`](https://github.com/go-kratos/kratos/blob/main/encoding/xml/xml.go). Uses the standard library `encoding/xml` package.
- **Form** (`x-www-form-urlencoded`): Located in [`encoding/form/form.go`](https://github.com/go-kratos/kratos/blob/main/encoding/form/form.go). Handles `application/x-www-form-urlencoded` data using `github.com/go-playground/form/v4`.

Additionally, the **MsgPack** codec is available as an optional contrib module at [`contrib/encoding/msgpack/msgpack.go`](https://github.com/go-kratos/kratos/blob/main/contrib/encoding/msgpack/msgpack.go), demonstrating the same registration pattern.

## The Codec Interface and Registry Architecture

At the heart of the system is the `Codec` interface defined in [`encoding/encoding.go`](https://github.com/go-kratos/kratos/blob/main/encoding/encoding.go):

```go
type Codec interface {
    Marshal(v any) ([]byte, error)
    Unmarshal(data []byte, v any) error
    Name() string               // the codec name → content‑subtype
}

```

The global registry maintains a map called `registeredCodecs` that stores instances indexed by their name. The `encoding.RegisterCodec()` function adds implementations to this map, making them available for content type negotiation.

## How to Register a Custom Codec in Kratos

Follow these steps to add support for proprietary formats like MessagePack, Avro, or custom binary protocols.

### 1. Implement the Codec Interface

Create a package that fulfills the three required methods:

```go
package mycodec

import "github.com/go-kratos/kratos/v2/encoding"

const Name = "myformat"   // will become the content‑subtype

type codec struct{}

func (c codec) Marshal(v any) ([]byte, error) {
    // convert v → []byte
}

func (c codec) Unmarshal(data []byte, v any) error {
    // fill v from data
}

func (c codec) Name() string { return Name }

```

### 2. Register in an Init Function

Add the registration logic to ensure the codec loads automatically:

```go
func init() {
    encoding.RegisterCodec(codec{})
}

```

### 3. Import with Blank Identifier

In your service's [`main.go`](https://github.com/go-kratos/kratos/blob/main/main.go) or initialization code, import the package to trigger the `init` function:

```go
import _ "path/to/your/module/mycodec"

```

### 4. Use via HTTP Headers or Programmatically

Once registered, Kratos automatically negotiates the codec based on headers:

```http
Content-Type: application/myformat
Accept: application/myformat

```

Or access it directly in code:

```go
c := encoding.GetCodec("myformat")
data, err := c.Marshal(myStruct)

```

## Default Fallback Behavior and Content Negotiation

When processing HTTP requests, Kratos determines the appropriate codec through the `CodecForRequest` function in [`transport/http/codec.go`](https://github.com/go-kratos/kratos/blob/main/transport/http/codec.go) (line 35). If the request does not specify a recognized `Content-Type` or `Accept` header, the framework defaults to the JSON codec. This ensures that APIs remain functional for clients that omit explicit format headers while still supporting content type negotiation for specialized consumers.

## Summary

- Kratos provides **five built-in content encoding formats**: JSON, Proto, YAML, XML, and Form, all registered in [`encoding/encoding.go`](https://github.com/go-kratos/kratos/blob/main/encoding/encoding.go).
- The framework uses a **global registry** (`registeredCodecs`) mapped by content-subtype strings.
- Adding custom formats requires implementing the **`Codec` interface** with `Marshal`, `Unmarshal`, and `Name` methods.
- Register custom codecs via **`encoding.RegisterCodec()`** inside an `init` function, then import with a blank identifier.
- **JSON serves as the default fallback** when no content type is specified, as implemented in [`transport/http/codec.go`](https://github.com/go-kratos/kratos/blob/main/transport/http/codec.go).

## Frequently Asked Questions

### What is the default content encoding format when a client omits the Content-Type header?

Kratos defaults to JSON encoding when no valid `Content-Type` or `Accept` header is present. This behavior is hardcoded in the `CodecForRequest` function within [`transport/http/codec.go`](https://github.com/go-kratos/kratos/blob/main/transport/http/codec.go), which returns the JSON codec as the final fallback option.

### Can I override the built-in JSON, Proto, or XML codecs with custom implementations?

Yes. While the built-in codecs register themselves in their respective `init` functions (e.g., [`encoding/json/json.go`](https://github.com/go-kratos/kratos/blob/main/encoding/json/json.go)), you can register a codec with the same name string after the default registration to override it. However, this is generally discouraged unless you need to modify serialization behavior globally, as it affects all transports using that content subtype.

### How does Kratos handle codec selection for gRPC versus HTTP transports?

For gRPC, the Proto codec is typically selected by default based on the gRPC protocol requirements. For HTTP, Kratos inspects the `Content-Type` and `Accept` headers via `CodecForRequest` in [`transport/http/codec.go`](https://github.com/go-kratos/kratos/blob/main/transport/http/codec.go) to determine the appropriate codec. Both transports share the same global registry in [`encoding/encoding.go`](https://github.com/go-kratos/kratos/blob/main/encoding/encoding.go), so custom codecs work across both protocols automatically.

### Where can I find a complete example of a custom codec implementation?

The repository includes a reference implementation in [`contrib/encoding/msgpack/msgpack.go`](https://github.com/go-kratos/kratos/blob/main/contrib/encoding/msgpack/msgpack.go). This file demonstrates the complete pattern: defining the codec struct, implementing the three interface methods, and registering via `encoding.RegisterCodec()` in an `init` function.