ethereum/go-ethereum · critical
clique (poa) sealing not supported any more
Error message
clique (poa) sealing not supported any more
What it means
Clique's Seal implementation unconditionally panics with 'clique (poa) sealing not supported any more'. In this codebase, the Clique engine is retained for verifying/reading PoA chains while block production (sealing new blocks through consensus.Engine.Seal) has been removed, so any attempt to mint a Clique block crashes by design.
Source
Thrown at consensus/clique/clique.go:593
// Finalize implements consensus.Engine. There is no post-transaction
// consensus rules in clique, do nothing here.
func (c *Clique) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state vm.StateDB, body *types.Body, blockAccessIndex uint32, bal *bal.ConstructionBlockAccessList) {
// No block rewards in PoA, so the state remains as is
}
// Authorize injects a private key into the consensus engine to mint new blocks
// with.
func (c *Clique) Authorize(signer common.Address) {
c.lock.Lock()
defer c.lock.Unlock()
c.signer = signer
}
// Seal implements consensus.Engine, attempting to create a sealed block using
// the local signing credentials.
func (c *Clique) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
panic("clique (poa) sealing not supported any more")
}
// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
// that a new block should have:
// * DIFF_NOTURN(2) if BLOCK_NUMBER % SIGNER_COUNT != SIGNER_INDEX
// * DIFF_INTURN(1) if BLOCK_NUMBER % SIGNER_COUNT == SIGNER_INDEX
func (c *Clique) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int {
snap, err := c.snapshot(chain, parent.Number.Uint64(), parent.Hash(), nil)
if err != nil {
return nil
}
c.lock.RLock()
signer := c.signer
c.lock.RUnlock()
return calcDifficulty(snap, signer)
}
func calcDifficulty(snap *Snapshot, signer common.Address) *big.Int {View on GitHub (pinned to 6bb0588ad8)
Solutions
- Do not attempt to seal with this engine; use it only to validate existing clique chains.
- For a new private/consortium chain, use a consensus engine whose Seal is supported (e.g. a supported PoA/Aura-style engine in your fork) or an external signer design.
- Remove --mine or validator sealing config targeting clique.
- Pin to an older go-ethereum version if clique sealing is a hard requirement, while tracking the security tradeoff.
Example fix
// before engine.Seal(chain, block, results, stop) // *clique.Clique -> panics // after // Use clique only for verification; produce blocks with a supported sealing engine.
Defensive patterns
Strategy: validation
Validate before calling
// guard before any sealing call
func canSeal(engine consensus.Engine) bool {
_, ok := engine.(interface{ SealSupported() })
return ok // clique.Clique does not advertise sealing in this build
} Type guard
func isClique(e consensus.Engine) bool {
_, ok := e.(*clique.Clique)
return ok
} Prevention
- Never wire clique.Clique into a miner/sealer path.
- Assert at startup that the configured engine supports sealing before enabling mining flags.
- Track which engines are verify-only in this codebase version.
When it happens
Trigger: Running a node configured to seal with clique (e.g. a miner/validator setup calling engine.Seal, --mine with clique without a supported sealer, or custom code invoking Seal on a *clique.Clique instance). Any path reaching clique.Seal panics.
Common situations: Old private-PoA setups or tutorials that used clique for block production upgraded to a version where sealing was removed; tools/tests that call Seal directly on the consensus engine.
Related errors
- ethash (pow) sealing not supported any more
- nil chainID
- error decoding contract deployer hex %s: %v
- Could not create random uuid: %v
- key generation: could not read from random source:
AI-assisted analysis of ethereum/go-ethereum@6bb0588ad8 (2026-08-15).
Data as JSON: /api/errors/cab8f715d2c78775.
Report an issue: GitHub.