microsoft/FASTER · error · FasterException

Wire format already registered

Error message

Wire format {wireFormat} already registered

What it means

FasterServerBase.Register attaches an ISessionProvider to a WireFormat enum value, but each wire format may have exactly one provider. If TryAdd fails because a provider is already registered for that wire format, FASTER throws FasterException. Registering twice is almost always an initialization-order bug, not something to retry.

Solutions

  1. Call Register only once per WireFormat; guard with a check or a registration flag.
  2. Call Unregister(wireFormat, out _) before re-registering to replace the provider.
  3. Use a different WireFormat value if you genuinely need multiple backends in the same server.

Example fix

// before
server.Register(WireFormat.DefaultWireFormat, provider1);
server.Register(WireFormat.DefaultWireFormat, provider2);
// after
server.Unregister(WireFormat.DefaultWireFormat, out _);
server.Register(WireFormat.DefaultWireFormat, provider2);
Defensive patterns

Strategy: validation

Validate before calling

if (!registeredFormats.Add(wireFormat)) return; // register each wire format exactly once
server.Register(wireFormat, provider);

Try / catch

try { server.Register(wireFormat, provider); } catch (FasterException) { server.Unregister(wireFormat, out _); server.Register(wireFormat, provider); }

Prevention

When it happens

Trigger: Calling server.Register(wireFormat, provider) with the same WireFormat value twice — e.g. two components each register the DefaultWireFormat, or a restart path re-registers without Unregister first.

Common situations: Multiple services in one host process each constructing/registrating providers for the same wire format; re-running initialization code on config reload; unit tests sharing a static server instance across tests.

Related errors


AI-assisted analysis of microsoft/FASTER@321d872eab (2026-09-15). Data as JSON: /api/errors/a9f93a5bf297016a. Report an issue: GitHub.

Appendix: source

Thrown at cs/remote/src/FASTER.server/Servers/FasterServerBase.cs:72

        public FasterServerBase(string address, int port, int networkBufferSize)
        {
            this.address = address;
            this.port = port;
            this.networkBufferSize = networkBufferSize;
            if (networkBufferSize == default)
                this.networkBufferSize = BufferSizeUtils.ClientBufferSize(new MaxSizeSettings());

            activeSessions = new ConcurrentDictionary<IMessageConsumer, byte>();
            sessionProviders = new ConcurrentDictionary<WireFormat, ISessionProvider>();
            activeSessionCount = 0;
            Disposed = false;
        }

        /// <inheritdoc />
        public void Register(WireFormat wireFormat, ISessionProvider backendProvider)
        {
            if (!sessionProviders.TryAdd(wireFormat, backendProvider))
                throw new FasterException($"Wire format {wireFormat} already registered");
        }

        /// <inheritdoc />
        public void Unregister(WireFormat wireFormat, out ISessionProvider provider)
            => sessionProviders.TryRemove(wireFormat, out provider);

        /// <inheritdoc />
        public ConcurrentDictionary<WireFormat, ISessionProvider> GetSessionProviders() => sessionProviders;

        /// <inheritdoc />
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public bool AddSession(WireFormat protocol, ref ISessionProvider provider, INetworkSender networkSender, out IMessageConsumer session)
        {
            session = null;

            if (Interlocked.Increment(ref activeSessionCount) <= 0)
                return false;

View on GitHub (pinned to 321d872eab)