Reported here https://github.com/bitcoin/bitcoin/pull/12629#issuecomment-381095603 by @Empact.  I've seen it now in a few different travis jobs, including:

https://travis-ci.org/bitcoin/bitcoin/jobs/366157920
https://travis-ci.org/bitcoin/bitcoin/jobs/366139851

From my initial investigation it seems like there may be an actual bug in block announcement, so I'm  opening this issue to track.
if (fNewBlock) *fNewBlock = true;
    if (!CheckBlock(block, state, chainparams.GetConsensus()) ||
        !ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindex->pprev)) {
        if (state.IsInvalid() && !state.CorruptionPossible()) {
            pindex->nStatus |= BLOCK_FAILED_VALID;
            setDirtyBlockIndex.insert(pindex);
        }
        return error("%s: %s", __func__, FormatStateMessage(state));
    }
    
    
    if (!IsInitialBlockDownload() && chainActive.Tip() == pindex->pprev)
        GetMainSignals().NewPoWValidBlock(pindex, pblock);
    
    try {
        CDiskBlockPos blockPos = SaveBlockToDisk(block, pindex->nHeight, chainparams, dbp);
        if (blockPos.IsNull()) {
            state.Error(strprintf("%s: Failed to find position to write new block to disk", __func__));
            return false;
        }
        if (!ReceivedBlockTransactions(block, state, pindex, blockPos, chainparams.GetConsensus()))
            return error("AcceptBlock(): ReceivedBlockTransactions failed");
    } catch (const std::runtime_error& e) {
        return AbortNode(state, std::string("System error: ") + e.what());
    }
    FlushStateToDisk(chainparams, state, FlushStateMode::NONE);
    CheckBlockIndex(chainparams.GetConsensus());
    return true;
}
bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock> pblock, bool fForceProcessing, bool *fNewBlock)