# IsNonVoting vs IsObserver in Dragonboat: Understanding Node Configuration Differences

> Understand IsNonVoting vs IsObserver node configurations in Dragonboat. Learn how IsObserver is a deprecated alias mapping to IsNonVoting for clearer node setup.

- Repository: [lni/dragonboat](https://github.com/lni/dragonboat)
- Tags: deep-dive
- Published: 2026-03-06

---

**IsNonVoting and IsObserver represent the identical node configuration in Dragonboat, with IsObserver serving as a deprecated alias that automatically maps to IsNonVoting during configuration validation.**

In the Dragonboat Raft library (`lni/dragonboat`), the `config.Config` struct provides two boolean fields that control whether a replica participates in log replication without voting power. Understanding the relationship between these fields ensures your cluster configuration remains compatible with future library versions while maintaining correct consensus behavior.

## What Are IsNonVoting and IsObserver in Dragonboat?

Both `IsNonVoting` and `IsObserver` configure a Raft replica that receives log entries from the leader but **does not participate in leader elections** and is **excluded from quorum calculations**. These nodes stay synchronized with the cluster state without affecting availability requirements.

In [`config/config.go`](https://github.com/lni/dragonboat/blob/main/config/config.go), the `Config` struct defines these fields:

```go
type Config struct {
    ReplicaID   uint64
    RaftAddress string
    IsNonVoting bool  // Official field
    IsObserver  bool  // Deprecated alias
    // ... other fields
}

```

## Key Differences Between IsNonVoting and IsObserver

While functionally equivalent at runtime, the fields differ in their support status and internal handling.

### Current Status and Deprecation

**IsNonVoting** is the officially supported, documented configuration option marked as production-ready. **IsObserver** is a deprecated legacy name retained only for backward compatibility. According to the Dragonboat CHANGELOG, the terminology was updated to align with the Raft paper's description of "non-voting members" (section 4.2.1).

### Configuration Validation Mapping

The distinction effectively disappears during configuration validation. In [`config/config.go`](https://github.com/lni/dragonboat/blob/main/config/config.go), the `Validate()` method explicitly maps the deprecated field to the current one:

```go
// config/config.go lines 173-186
func (c *Config) Validate() error {
    // ... other validation logic ...
    if c.IsObserver {
        c.IsNonVoting = true // Observer is just an alias
    }
    // ... remainder of validation ...
}

```

This means setting `IsObserver: true` results in `IsNonVoting` being set to `true` internally, producing identical runtime behavior.

## Practical Implementation: Configuring Non-Voting Nodes

When implementing non-voting replicas in your Dragonboat deployment, use the current APIs and configuration fields to ensure future compatibility.

### Using IsNonVoting (Recommended)

Configure the node at startup by setting `IsNonVoting` in the replica configuration:

```go
cfg := dragonboat.Config{
    ReplicaID:        2,
    RaftAddress:      "10.0.0.2:63001",
    IsNonVoting:      true,   // Official field
    // IsObserver: true,      // Deprecated - do not use
}

err := nh.StartReplica(shardID, replicaID, stateMachineFactory, cfg)
if err != nil {
    // handle error
}

```

### Using RequestAddNonVoting API

For dynamic cluster membership changes, use the `RequestAddNonVoting` method on `NodeHost`:

```go
// Request addition of non-voting replica
rs, err := nh.RequestAddNonVoting(
    shardID,               // cluster shard ID
    replicaID,             // unique replica ID
    "10.0.0.2:63001",      // Raft address
    0,                     // configChangeIndex (0 = auto)
    10*time.Second,        // timeout
)
if err != nil {
    // handle request error
}

// Wait for completion
if err := rs.Completed().Err; err != nil {
    // handle completion error
}

```

This API is defined in [`nodehost.go`](https://github.com/lni/dragonboat/blob/main/nodehost.go) (lines 1170-1186) and provides the preferred mechanism for adding non-voting members without requiring configuration file changes.

### Legacy IsObserver Usage (Deprecated)

While existing code using `IsObserver` continues to function, the field will eventually be removed:

```go
// Legacy code - still works but not recommended
cfg := dragonboat.Config{
    ReplicaID:   2,
    RaftAddress: "10.0.0.2:63001",
    IsObserver:  true,  // Maps to IsNonVoting during validation
}

```

The Dragonboat CHANGELOG explicitly warns that `IsObserver` is deprecated in favor of `IsNonVoting`.

## Summary

- **IsNonVoting and IsObserver are functionally identical** – both configure replicas that receive log entries without voting rights or quorum membership.
- **IsNonVoting is the current, supported field** located in `config.Config` and marked as production-ready.
- **IsObserver is a deprecated alias** that `config.Config.Validate()` automatically maps to `IsNonVoting` for backward compatibility.
- **Use `RequestAddNonVoting`** for dynamic membership changes and set `IsNonVoting: true` in configuration structs for new deployments.

## Frequently Asked Questions

### What is the difference between IsNonVoting and IsObserver in Dragonboat?

There is no functional difference. `IsObserver` is a deprecated alias for `IsNonVoting`. When `config.Config.Validate()` runs, it sets `IsNonVoting = true` if `IsObserver` is true, making them behave identically at runtime. Use `IsNonVoting` for all new code.

### Is IsObserver still supported in Dragonboat?

Yes, but only for backward compatibility. The field still works because the validation logic in [`config/config.go`](https://github.com/lni/dragonboat/blob/main/config/config.go) maps it to `IsNonVoting`, but it is marked as deprecated in the CHANGELOG and will be removed in a future release. Migrate existing code to use `IsNonVoting` to avoid breaking changes.

### How do I add a non-voting node to a Dragonboat cluster?

Use the `NodeHost.RequestAddNonVoting` method, which handles the membership change protocol. Provide the shard ID, replica ID, Raft address, and timeout. Alternatively, start a replica with `IsNonVoting: true` in the `Config` struct passed to `StartReplica`, then use the standard membership change APIs to add it to the cluster view.

### Can a non-voting node be promoted to a voting member?

Yes. A non-voting replica can be promoted to a full voting member using the membership change APIs such as `RequestAddReplica`. Because the node already has the complete log from participating in replication, promotion requires only a configuration change to grant it voting rights rather than a full state transfer.