This schema is ossified and no longer actively developed. Please report problems via GitHub issues.

Dynamic Configuration
for IPFS Mainnet

Updateable system registry for routing systems, bootstrap peers, special TLD resolvers, and delegated endpoints.

Overview

IPFS Mainnet AutoConf provides a standardized, extensible configuration format for IPFS implementations to discover and configure routing systems, bootstrap peers, DNS resolvers for special TLDs, and delegated endpoints dynamically.

What is AutoConf?

This version introduces a system-centric approach that moves away from hardcoded profiles to a flexible registry where routing systems declare their capabilities and endpoints specify which systems they support. This enables:

  • Dynamic System Discovery: New routing systems can be added without breaking existing clients
  • Future-Proof API Versioning: Endpoints can support multiple API versions simultaneously
  • Clear Separation: Native configuration (bootstrap peers) vs delegated configuration (HTTP endpoints)
  • Client Choice: Implementations decide whether to use native or delegated routing per system
  • API Compatibility: Clients ignore unknown APIs and use only the endpoints they understand

Key Principles

  1. Extensibility: Unknown APIs are safely ignored, allowing gradual ecosystem evolution
  2. Endpoint-Level Capabilities: Each endpoint declares exactly which APIs it supports
  3. Configurable Caching: Clients cache configurations locally, for the shorter of AutoConfTTL and their own refresh interval

Configuration Format

The AutoConf format consists of the following sections that work together to provide comprehensive routing configuration:

AutoConfVersion

Purpose: Timestamp-based version identifier (YYYYMMDDNN format), similar to DNS SOA sequence numbers

Usage: Identifies a published revision, so operators and logs can name the exact configuration a node is running. Clients detect changes via HTTP ETag and Last-Modified rather than by comparing this number.

Example: 2025072801 (July 28, 2025, version 01)

AutoConfSchema

Purpose: Schema version number for breaking changes

Usage: Allows clients to handle different config formats

Current: 1

AutoConfTTL

Purpose: Cache duration in seconds

Usage: A hint for how long clients should cache the config. Clients use the shorter of this value and their own configured refresh interval, so this can bring a refresh forward but never push it back.

Default: 86400 (24 hours)

SystemRegistry

Purpose: Discovery registry of all routing systems

Contains: Link to documentation, native configuration, and delegated API capabilities

Usage: Clients check here to understand system capabilities

Note: InfoURL and Description are for people reading this document. Clients do not consume them.

DNSResolvers

Purpose: DNS-over-HTTPS resolvers for special TLDs

Usage: Resolving non-ICANN domains like .eth

Format: Maps eTLD to array of DoH endpoints

Note: Implementations use default resolver from the OS or explicitly choose DoH resolver (e.g. in browsers)

DelegatedEndpoints

Purpose: HTTP endpoints that provide routing services via delegation

Contains: Endpoint URL, supported systems, Read/Write API paths

Usage: Clients use these when they don't have native system support

Well Known Routing Systems

The registry defines routing systems with their capabilities and access methods:

System Routing Types

IPFS routing systems can operate in different modes depending on client capabilities and requirements:

🔌
Native
Direct implementation within the client
Examples: DHT participation, local DNS resolver
Best for: Full nodes, daemons with persistent connectivity
🌐
Delegated
Access via HTTP endpoints
Used when native support is unavailable or impractical
Best for: Browsers, mobile apps, resource-constrained environments
🔀
Hybrid
Both native and delegated support available
Clients choose based on their capabilities and constraints
Best for: Flexible implementations that adapt to environment

Implementation Decision Flow

Does your client support native implementation?
YES
🔌
Use Native Config Bootstrap peers, direct DHT participation
NO
🌐
Use Delegated Endpoints HTTP routing via configured endpoints
System Type Purpose APIs
AminoDHT 🔀 Native + Delegated P2P content and peer routing via Kademlia DHT /routing/v1/{providers,peers,ipns} (R/W for ipns)
IPNI 🌐 Delegated Only Fast content discovery from large storage providers /routing/v1/providers
Example 🌐 Delegated Only Test system for verifying graceful handling of unknown APIs /example/v0/{read,write}

Adding New Systems

The schema supports gradual ecosystem evolution: add systems to the registry with their API paths, update endpoints to declare support, and existing clients will ignore unknown APIs while new clients can leverage them immediately.

This extensibility mechanism allows IPFS Mainnet to introduce new routing systems by providing delegated HTTP adapters that existing software can understand and query. For example, a novel routing system can be deployed with HTTP endpoints that speak the standard routing protocols, enabling immediate adoption without requiring native implementation support from existing IPFS clients. This approach enables:

  • Zero-friction deployment: New systems work immediately with all existing IPFS implementations that support delegated routing
  • Gradual native adoption: Implementations can add native support over time while using delegation as a bridge
  • Innovation without fragmentation: Experimental routing systems can be tested in production without breaking compatibility
  • Backward compatibility: Older clients continue working, simply ignoring systems they don't recognize

Client Implementation

Clients should process the configuration by checking available systems, determining native vs delegated routing support, and configuring DNS resolvers for special TLDs.

API Versioning Strategy

Delegated utility servers can support multiple API versions simultaneously:

API Version Evolution Example
{
  "DelegatedEndpoints": {
    "https://future-endpoint.example": {
      "Systems": ["AminoDHT", "NewSystem"],
      "Read": [
        "/routing/v1/providers",    // Legacy API
        "/routing/v2/providers",    // Enhanced API
        "/routing/v2/content"       // New capability
      ],
      "Write": [
        "/routing/v1/ipns",         // Legacy publishing
        "/routing/v2/ipns"          // Enhanced publishing
      ]
    }
  }
}

Implementations Status

The Go ecosystem fetches this document at runtime today. The JavaScript ecosystem reaches the same endpoints indirectly, by pinning equivalent values at build time rather than fetching them, so it does not pick up changes published here. Tracked in #3.

Implementation Status Since Notes
boxo/autoconf ✅ Shipped v0.42.1 Reference client. The Go implementations below all use it.
Kubo ✅ Shipped v0.37.0 Configured via AutoConf.
Rainbow ✅ Shipped v1.24.0 Enabled by default via RAINBOW_AUTOCONF, --autoconf-url to override.
Someguy ✅ Shipped v0.16.0 --autoconf / SOMEGUY_AUTOCONF.
Helia ☑️ Indirect v2.1.0 Hardcodes both the bootstrap peer list and https://delegated-ipfs.dev as the default delegated router.
helia-verified-fetch ☑️ Indirect v1.0.0 Falls back to https://delegated-ipfs.dev when no routers are supplied. Present since its first release.
Service Worker Gateway ☑️ Indirect v1.0.0 Hardcodes https://delegated-ipfs.dev for both routing and DNS. Present since its first release.

Processing Algorithm

Pseudo-code
// 1. Check SystemRegistry for available routing systems
for system in autoconf.SystemRegistry:
    if client.supportsNative(system):
        // Use native implementation with NativeConfig
        client.configureNative(system, autoconf.SystemRegistry[system].NativeConfig)
    else:
        // Use delegated routing via HTTP endpoints
        for endpoint in autoconf.DelegatedEndpoints:
            if system in endpoint.Systems:
                // Filter to only APIs this client recognizes
                supportedReadAPIs = client.filterKnownAPIs(endpoint.Read)
                supportedWriteAPIs = client.filterKnownAPIs(endpoint.Write)
                // Configure delegated routing using only supported APIs
                client.configureDelegated(system, endpoint, supportedReadAPIs, supportedWriteAPIs)

// 2. Configure DNS resolvers for special TLDs
// Note: Implementations use OS default or explicit DoH resolver
for etld, resolvers in autoconf.DNSResolvers:
    client.configureDNS(etld, resolvers)

Example Implementation

JavaScript Client Example
async function configureIPFS() {
    // Fetch AutoConf
    const response = await fetch('https://conf.ipfs-mainnet.org/autoconf.json');
    const autoconf = await response.json();
    
    // Cache for the shorter of our own interval and AutoConfTTL from the config
    const maxCacheSeconds = 24 * 60 * 60; // 24 hours
    const cacheTTL = Math.min(maxCacheSeconds, autoconf.AutoConfTTL || maxCacheSeconds);
    localStorage.setItem('ipfs-autoconf', JSON.stringify({
        data: autoconf,
        expires: Date.now() + (cacheTTL * 1000)
    }));
    
    // Define which systems this client supports natively
    const nativeSystems = ['AminoDHT']; // This client has native DHT support
    
    // Configure routing systems
    for (const [systemName, systemConfig] of Object.entries(autoconf.SystemRegistry)) {
        if (nativeSystems.includes(systemName)) {
            // Use native implementation
            if (systemName === 'AminoDHT' && canRunDHT()) {
                configureNativeDHT(systemConfig.NativeConfig.Bootstrap);
            }
        } else {
            // Delegate to HTTP endpoints for unsupported systems
            for (const [url, endpoint] of Object.entries(autoconf.DelegatedEndpoints)) {
                if (endpoint.Systems.includes(systemName)) {
                    configureDelegatedRouting(systemName, url, endpoint);
                }
            }
        }
    }
    
    // Configure DNS resolvers for special TLDs
    // Note: Use OS default resolver or explicit DoH for general domains
    for (const [etld, resolvers] of Object.entries(autoconf.DNSResolvers)) {
        configureDNSResolver(etld, resolvers);
    }
}

Failure Behavior

Losing this server must never take a node off the network. Here is how the reference implementation, boxo/autoconf v0.42.1, does it.

Configuration comes from three sources. Any failure falls through to the next:

  1. The network. Validated before it is used or stored.
  2. The cached copy, at any age. Log how old it is and carry on.
  3. Defaults built into the client. What a node with no cache uses.

Every failure behaves the same. DNS failure, refused connection, timeout, 404, 500, an HTML error page, malformed JSON, an oversized body: all mean no usable response, all fall through.

Validate before caching. A broken or hostile response then cannot poison the copy a node falls back on.

Reference limits, sane defaults rather than requirements: 2 MiB response cap, 5 second timeout, 24 hour refresh. Within that interval the cached copy is used without contacting the server, and ETag and Last-Modified make an unchanged document cost a 304 and no body.

Implementation Guidance

Different IPFS implementations have different constraints and capabilities. Here are recommendations for common deployment scenarios:

🌐 Browser Implementations

Constraints: Limited networking, no raw sockets, CORS restrictions

Recommendations:

  • Prefer delegated routing for all systems
  • Use HTTPS endpoints exclusively
  • Implement aggressive caching
  • Consider service worker integration
// Browser-optimized configuration
const browserDefaults = {
    preferDelegated: ['AminoDHT', 'IPNI'],
    enableNative: [] // No native routing in browsers
};

🖥️ Daemon Implementations

Capabilities: Full networking, persistent storage, background processing

Recommendations:

  • Prefer native DHT participation
  • Use delegated routing for specialized systems (IPNI)
  • Enable both TCP and QUIC transports
  • Participate in content providing (native AminoDHT only)
// Daemon-optimized configuration
const daemonDefaults = {
    preferNative: ['AminoDHT'],
    preferDelegated: ['IPNI'],
    enableProviding: true // Only works with native AminoDHT
};

📱 Mobile/Resource-Constrained

Constraints: Battery life, bandwidth limits, intermittent connectivity

Recommendations:

  • Hybrid approach based on network type
  • Delegated routing on cellular
  • Optional native DHT on WiFi
  • Aggressive connection pruning
// Mobile-optimized configuration
const mobileDefaults = {
    preferDelegated: ['AminoDHT', 'IPNI'],
    enableNativeOnWifi: ['AminoDHT'],
    maxConnections: 50
};

Platform-Specific Considerations

Implementers should make these decisions at build time based on their target platform rather than reading them from the autoconf. The autoconf provides the what (available systems and endpoints), while your implementation decides the how (native vs delegated routing).

Implementation Decision Tree
// Instead of reading profiles from autoconf, hard-code platform decisions:
function getRoutingStrategy() {
    if (typeof window !== 'undefined' && !window.require) {
        // Browser environment
        return { preferDelegated: true };
    } else if (process.env.IPFS_LITE_MODE) {
        // Resource-constrained environment
        return { preferDelegated: true, maxConnections: 50 };
    } else {
        // Full daemon environment
        return { preferNative: true, enableProviding: true }; // Providing requires native AminoDHT
    }
}

This approach provides clearer separation between configuration data (what services are available) and implementation decisions (how to use those services), making both the autoconf and implementations simpler and more maintainable.

Security Considerations

Fetching defaults over the network adds a party you have to trust. This section covers how changes to this document are controlled, and what to do if depending on it at runtime is not acceptable for your deployment.

Publishing controls

This document is published from a public repository, so every revision and its author are on the record and any change can be diffed against what came before. Proposed changes are checked in CI with the same client that nodes run: a document that carries no bootstrap peers, or that does not advance AutoConfVersion, fails that check.

If you need stronger guarantees

For deployments where losing control of routing is unacceptable, do not depend on this service at runtime:

  • Turn it off and supply your own values. In Kubo, ipfs config profile apply autoconf-off sets AutoConf.Enabled to false and empties Bootstrap, DNS.Resolvers, Routing.DelegatedRouters and Ipns.DelegatedPublishers. It empties those fields rather than filling them in, so you must populate the ones you need before the node is useful.
  • Serve your own copy. Point AutoConf.URL at a document you host and update on your own schedule, after reviewing what changed here.
  • Keep a floor. Whatever you do, retain a set of bootstrap peers and endpoints that works without this service, so an outage or a bad publish cannot leave your nodes with nowhere to connect. A client can also build this floor for itself: boxo/bootstrap periodically saves a sample of currently connected peers as temporary bootstrappers, so a node that has been online before does not depend on the published list alone.