1 pontos por GN⁺ 2 시간 전 | 1 comentários | Compartilhar no WhatsApp
  • O banco de dados detectou hoje um UUID v4 duplicado, e o valor existente era exatamente igual a b6133fd6-70fe-4fe3-bed6-8ca8fc9386cd, de um registro adicionado em 2025
  • O pacote em uso é o uuid do npm, e dizem que o processo é gerar com import { v4 as uuidv4 } from "uuid"; e depois const document_id = uuidv4();, inserindo então no banco de dados
  • Há apenas cerca de 15.000 registros no banco de dados, então isso parece estatisticamente impossível, e a pessoa está perguntando se mais alguém já passou pelo mesmo

1 comentários

 
GN⁺ 2 시간 전
Comentários do Hacker News
  • jandrewrogers: Isso é surpreendentemente comum. A segurança do UUIDv4 depende da premissa de que existe uma fonte de entropia de alta qualidade, mas essa premissa quebra facilmente por falhas de hardware, bugs comuns de software e pela falta de compreensão dos desenvolvedores sobre entropia
    Detectar que a fonte de entropia está quebrada é bem caro, então quase ninguém faz isso, e no fim só descobre depois que a colisão acontece. Por isso, em muitos sistemas de alta confiabilidade e alta garantia, o UUIDv4 é explicitamente proibido

    • LocalH: Foi por isso que a CloudFlare criou coisas como a parede de lâmpadas de lava. Não tanto por ser, por si só, uma fonte gigantesca de entropia, mas porque torna visível até para quem não entende bem geração aleatória e o conceito de entropia
      Quanto mais fontes de entropia, melhor, e uma boa parte delas deve ser não determinística. Mesmo em jogos pequenos, se você misturar no seed inicial valores como coordenadas do mouse, intervalo entre cliques de botão e número de frames antes de apertar start, fica muito mais difícil prever, mesmo usando internamente um gerador pseudoaleatório. Eu ficaria decepcionado se a CloudFlare usasse menos de 100 fontes de entropia
    • Groxx: Já vi duplicatas plausíveis vindas de hardware defeituoso. E em algumas bibliotecas de UUID também era muito comum aquele padrão de duplicação com a parte final preenchida com zeros
      Isso acontece quando você não valida o valor de retorno, como no velho caso do Go: “pedi N bytes, mas só recebi 3, então preciso pedir os N-3 bytes restantes”. Na maioria dos hardwares e sistemas operacionais isso quase nunca explode, então ninguém confere, e um dia aparece em produção como dezenas de milhares de colisões
    • thecloud: Fiquei curioso sobre quais alternativas usam em sistemas de alta confiabilidade no lugar de UUIDv4
  • throwaway_19sz: Parece uma história engraçada e inacreditável, mas é real. Há 10 anos um amigo entrou como CTO numa startup de alto crescimento, numa empresa com uns 200 desenvolvedores, e na primeira semana descobriu que existia um microsserviço dedicado só a gerar UUID
    Havia 3 engenheiros dedicados a um único endpoint, além até de gente de banco de dados. Sempre que um time precisava de um UUID novo “seguro”, tinha que chamar esse serviço, que gerava o UUID, verificava no próprio banco se já existia um igual emitido antes, e se não existisse inseria e então retornava. Não sei se era pela paz de espírito, mas esse time ainda rodava seu próprio quadro Kanban e seus próprios sprints

    • Aurornis: No começo trabalhei em startups com recursos limitados, então toda vez que construíamos algo ou contratávamos alguém a decisão era bem pensada. Naquela época essa história pareceria ficção
      Depois entrei em startups onde toda vez que alguém inventava uma nova preocupação surgiam um novo microsserviço e um novo time. A meta trimestral explicitamente era aumentar o tamanho da equipe de engenharia, e times de 3 ou 4 pessoas inventavam trabalho para si mesmos nos próprios sprints e reuniões de planejamento. Sugeri mover gente de projetos estáveis para tarefas urgentes, mas barraram isso porque entrava em conflito com o KPI de aumentar o número de engenheiros até um certo valor
    • wongarsu: Em algum momento alguém vai otimizar isso com um contador global incremental de 128 bits para a empresa inteira. Em vez de consultar um banco cada vez maior, basta pegar o contador atual, incrementar em 1 e distribuir; é O(1) e rápido
      Para alta disponibilidade e implantação global, também dá para shardear, dando a cada instância uma faixa dedicada de IDs. Basta reservar alguns bits mais altos para o ID do datacenter e alguns bits para a instância geradora dentro dele. Espera, acho que já vi isso em algum lugar... Fico curioso se o Twitter ainda usa esse modelo ou se acabou mudando
    • roryirvine: Vi algo parecido nas profundezas de uma grande empresa de tecnologia do Vale do Silício. Só que era mais complicado porque a lista mestre dos UUIDs em uso ficava num serviço externo de CMDB operado por outro departamento
      Todo dia recebiam um dump do banco para checar na geração de IDs “temporários”, e eles só viravam “definitivos” depois de enviados corretamente ao CMDB. Havia guard rails para impedir que IDs temporários fossem usados em produção, e até um processo para reciclar IDs definitivos não utilizados. Da última vez que soube, eles estavam havia 18 meses num projeto de 6 meses para mover o cache local de banco para o Zookeeper
  • CodesInChaos: Normalmente isso acontece por causa de um gerador pseudoaleatório mal semeado. Importa saber se o UUID foi criado no backend ou no frontend
    O frontend é inerentemente difícil de confiar por vários motivos, inclusive colisões intencionais, então é preciso tratar colisões. No backend dá para fazer isso de forma confiável. Antigamente isso acontecia em VMs, mas hoje em dia já deveria estar resolvido; ainda assim, pode ocorrer se processos fortemente sandboxados usarem um caminho alternativo de aleatoriedade inseguro. Fork de processo ou de VM também pode criar colisões por cópia de estado

    • danpalmer: Já ouvi dizer que a Segment, empresa de analytics, apoiava o produto inteiro em UUIDs gerados no navegador. Estavam tendo colisões de UUID no navegador por todo lado, e parecia que o produto, no fundo, não conseguia gerar dados úteis. Espero que já tenham corrigido isso
  • kst: Isso me lembrou uma passagem de “Pro Git”. <https://git-scm.com/book/en/v2>
    O exemplo dizia que, mesmo se os 6,5 bilhões de pessoas da Terra criassem a cada segundo código no volume do histórico inteiro do kernel Linux e empurrassem tudo para um único repositório Git gigantesco, ainda levaria cerca de 2 anos para a chance de colisão de objetos SHA-1 chegar a 50%. Por isso gostei da frase de que uma colisão natural de SHA-1 é menos provável do que todos os membros da equipe morrerem na mesma noite em ataques de lobos não relacionados entre si. Hash SHA-1 não é número aleatório e tem 160 bits, então é diferente de UUIDv4, mas gostei da metáfora dos ataques de lobos não relacionados

    • mega_dean: Isso me lembrou esta página que explica o tamanho absurdo do número de permutações ao embaralhar um baralho: https://czep.net/weblog/52cards.html
      É aquela metáfora de dar uma volta na Terra no equador a cada bilhão de anos, tirando uma gota d'água do Pacífico a cada volta e, quando o oceano secar, colocar uma folha de papel; repetir isso até a pilha chegar ao Sol, e ainda assim os três primeiros dígitos do cronômetro de 52! segundos não mudarem
    • swiftcoder: Por outro lado, ataques de dicionário são bem reais e bastante problemáticos, como podem testemunhar as pessoas que deram commit sem pensar naquele arquivo de caso de teste no Git
    • TacticalCoder: O time do Git não estava trabalhando pesado para oferecer opcionalmente outro hash além de SHA-1, como SHA256?
  • e12e: Tem uma discussão relacionada aqui: https://github.com/uuidjs/uuid/issues/546
    Por exemplo, há um relato de que crypto.getRandomValues() testado no googlebot era determinístico

    • D2OQZG8l5BI1S06: Faz sentido. Só não entendo por que alguém geraria UUID no navegador. Parece derrotar o propósito
  • adyavanapalli: O que está sendo descrito aqui é tão raro que, neste exato momento, a chance de a Terra inteira ser destruída por um asteroide é maior

    • thomasmg: Não é tão raro assim. Fiz as contas e era mais raro do que ser atingido por um meteorito, e cheguei a adicionar isso junto com o problema do aniversário no artigo da Wikipedia sobre UUID. Foi removido e substituído alguns anos depois
      Lembro de ter ouvido sobre uma mulher que realmente foi atingida por um meteorito e sobreviveu com ferimento na perna. Se houve colisão de UUID, a chance esmagadoramente maior é de bug de software ou falha no computador, embora também possa ser raio cósmico. Raios cósmicos mexendo em memória ou CPU são mais comuns do que as pessoas imaginam
    • delichon: É mais ou menos a chance de um asteroide digitar reticências e apertar o botão de adicionar comentário
    • spindump8930: Como outras pessoas disseram, se você der um seed ruim, isso vira algo bem comum. Em analogia, seria como a Terra estar cercada por um cinturão de asteroides denso estilo ficção científica
  • juancn: Não seria inicialização estranha do gerador aleatório ou falta de entropia? Se ninguém customizou nada, ele usa crypto.getRandomValues(rnds8), e getRandomValues não especifica uma quantidade mínima de entropia

    • Hizonner: É quase certo que o gerador aleatório estava gravemente errado, provavelmente por problema de seed. E há boa chance de isso também estar quebrando a criptografia
  • Geee: Pela interpretação de muitos mundos da mecânica quântica, deve existir algum ramo do universo em que todos os UUIDs são iguais. Fico imaginando o que as pessoas de lá pensam

    • suprjami: Provavelmente, depois de gerar “aquele UUID”, elas acrescentariam um número incremental no final para torná-lo único. Problema resolvido
    • BobaFloutist: E não só isso: deve haver muito mais universos quase idênticos ao nosso, exceto por um único UUID diferente. Só que eles ainda não chegaram a usá-lo. Ou então universos em que só os dois primeiros UUIDs são únicos e todos os seguintes são um desses dois
    • nyantaro1: É por isso que não gosto muito da abordagem estilo Everett
  • mittermayr: Concordo totalmente que isso não faz sentido. Ainda assim, chutando, antes talvez o UUIDv4 fosse gerado no celular do usuário e enviado ao banco, enquanto hoje de manhã o UUID que colidiu foi gerado num servidor Ubuntu
    Não sei exatamente como o UUIDv4 é gerado nem se características da máquina entram no algoritmo, mas a única mudança que me vem à cabeça é que antes era gerado no dispositivo e, há alguns meses, passou a ser gerado no servidor

    • AntiUSAbah: Vocês deixavam o usuário gerar o UUID? Sinceramente, me parece mais provável alguma implementação esquisita do que uma colisão real de UUID. Fiquei curioso sobre como o banco sinalizou essa colisão
    • wongarsu: Se ambos os UUIDs tivessem sido gerados em dispositivos, eu entenderia melhor a possibilidade de colisão. Já houve casos em aparelhos baratos em que o seed do gerador aleatório não era bem estabelecido e os valores “aleatórios” acabavam colidindo; fica pior ainda se a biblioteca usa um gerador barato em vez de um gerador criptograficamente seguro
      Mas no servidor, especialmente em 2026, isso não deveria acontecer. Antigamente seed de aleatoriedade em VM já foi um problema, mas hoje deveria ser menos. Mesmo que um dos UUIDs tenha sido gerado de forma ruim, a chance de um UUID realmente aleatório colidir com ele ainda é muito baixa; então os dois geradores provavelmente precisariam estar com problema
    • stubish: Colisão de UUIDv4 é estatisticamente extremamente improvável. O mais plausível é que dois sistemas tenham usado o mesmo seed. Se o seed tiver só alguns bytes, a probabilidade de colisão sobe de uma em bilhões para uma em milhões
  • dweez: Hora de reler este texto divertido: https://jasonfantl.com/posts/Universal-Unique-IDs/
    Se transformássemos o universo inteiro em um computador gigante dedicado a gerar UUIDs até a morte térmica, de quantos bits o espaço de IDs precisaria?

    • CodeWriter23: Se vai tão longe assim, isso aqui é obrigatório: https://www.decisionproblem.com/paperclips/
    • ipaddr: O exemplo de “você se preocupa se todos os humanos na Terra vão ser atingidos por meteoritos agora?” talvez não seja tão bom. Um único meteorito pode acabar com o mundo e, dado tempo suficiente, essa possibilidade cresce bastante
  • beejiu: Fiquei curioso se o UUID é gerado no cliente ou no servidor. Se for no cliente, pode ser por causa de bots de crawler. Por exemplo, o Googlebot executa JavaScript com “aleatoriedade” determinística

    • adzm: No incidente anterior desse pacote, a conclusão também foi a falta de aleatoriedade do Googlebot: https://github.com/uuidjs/uuid/issues/546
    • AgentME: Quase certamente é esse o caso, ou então usaram uma versão antiga do pacote que não conseguia usar corretamente o gerador aleatório do sistema, ou carregaram um polyfill velho e quebrado que reimplementa a API crypto do JS, ou ainda têm uma configuração de hospedagem esquisita em que o mesmo snapshot de VM é retomado em vários servidores e o estado da aleatoriedade acaba clonado
      Explicações desse tipo são várias ordens de grandeza mais plausíveis do que uma colisão realmente aleatória
  • merlindru: Tem cara de problema de seed. Se você conseguir provar que não é, talvez fique um pouco famoso

  • erlkonig: Sempre digo ao time que, com dados suficientes, valores aleatórios eventualmente podem colidir, e aí descobrimos quão robusto o software realmente é
    Mesmo assim, há muitos desenvolvedores experientes, líderes de equipe e CIOs que acreditam que isso é impossível e não escrevem nenhum código para tratar a situação. Aí um gerador aleatório ruim pode destruir o sistema muito antes do esperado, com corrupção simultânea inclusive sem detecção e regeneração. Me parece da mesma categoria de quem não verifica se malloc() deu certo. Costumo perguntar: “se é impossível, então não estamos usando bits demais?”

  • leni536: Não foi acaso; tem um bug em algum lugar. Pelo que vi por alto, o pacote parece chamar crypto.randomUUID() do runtime JS, e isso sempre deveria estar corretamente semeado
    A possibilidade de haver bug no runtime parece extremamente baixa, mas nunca se sabe. Fiquei curioso sobre qual runtime JS estão usando

  • jbverschoor: A causa mais plausível é que o pacote de geração aleatória de que uuid depende foi comprometido recentemente para tornar os números “aleatórios” previsíveis. Como resultado, um ataque de supply chain pode ter colocado em risco vários projetos de criptografia, SSL e moedas

    • jbverschoor: Há 3 semanas, em uuid/src/rng.ts, o array aleatório virou const. Todas as chamadas passaram a compartilhar o mesmo array aleatório
      Como chamadas subsequentes atualizam o código aleatório anterior, boa sorte se você gerou algo importante. O código antigo fazia um slice() para criar uma cópia nova. Pode ter sido uma mudança não intencional, mas eu nem entendo como isso passou, porque um teste que gerasse dois números aleatórios e verificasse se são diferentes provavelmente já falharia
  • pif: Mesmo com uma fonte de entropia de alta qualidade, você não consegue transformar “provavelmente será assim” em “necessariamente será assim”. Se você precisa de algo difícil de adivinhar, procure a criptografia; mas se precisa de unicidade garantida, precisa construir isso você mesmo

  • athrowaway3z: Uma regra prática simples é pensar se dá para colocar um timestamp no ID além do valor aleatório. Na maioria das vezes, a resposta é sim, e UUIDv7 já basta
    Se você analisou o problema a ponto de conseguir escrever uma prova de que o vazamento de informação é inaceitável, parabéns. Seu sistema provavelmente já é complexo e lento o suficiente para usar um hash criptográfico forte ou, se quiser evitar trabalho, UUIDv5

  • darqis: O PostgreSQL 18 tem suporte nativo a uuidv7, e o padrão pode ser unique com uuid7()

  • tumdum_: É um gerador pseudoaleatório com seed ruim

  • serf: É algo na ordem de 1 em 4,72 × 10²⁸, ou seja, 1 em 47,3 octilhões. Se fosse real, antes de comprar bilhete de loteria eu suspeitaria de condição de corrida ou de algum outro erro simples

    • petee: Sempre vi do jeito oposto. Se você já teve uma sorte dessas, a chance de outra sorte vir em seguida só fica menor, então é hora de economizar o dinheiro
    • k4rli: Esse papo de loteria não faz sentido. Se algo estatisticamente tão improvável já aconteceu, então acontecer de novo deveria ser ainda mais improvável
  • evnix: Mesmo deixando a matemática de probabilidades de lado, a realidade em que vivemos é tal que, mesmo com o melhor gerador aleatório de hardware, a aleatoriedade pode ser menor do que parece
    Onde segurança não é tão crítica, eu migraria para algo como TSID ou então para uuidv7, para que isso praticamente não aconteça no mundo real. Acho melhor do que complicar demais o código com retries

  • jordiburgos: Só peço que não usem b6133fd6-70fe-4fe3-bed6-8ca8fc9386cd. Fui checar no meu banco e já estava em uso

    • rich_sasha: Sempre achei uma loucura gerar UUID de forma aleatória. Agora só uso LLM. O prompt é: “Gere um UUID. Verifique se ninguém jamais o usou em nenhum código nem banco de dados. Revise seu trabalho e pense profundamente em cada etapa. Não imprima raciocínio nem inglês comum, apenas o próprio UUID.” De nada
    • mittermayr: Eu sabia. Estamos todos recebendo UUIDs baratos, e os bons ficam reservados para os grandões
    • robshep: Eu uso 16b55183-1697-496e-bc8a-854eb9aae0f3 e provavelmente há mais alguns. Se todo mundo postar aqui sua lista, não daria para verificar duplicatas?
  • pyuser583: Fiquei curioso sobre qual UUID é preferido hoje em dia

  • smokel: Já aconteceu várias vezes de eu culpar compilador, raio cósmico, efeito quântico ou no mínimo algum bug obscuro de kernel, para depois descobrir que o culpado era eu mesmo
    Colisão em 15.000 registros é improvável demais, então eu suspeitaria primeiro de outras causas: tratamento de duplicatas, requisições reenviadas, objeto reutilizado, logs enganosos, reutilização de identificadores em outro caminho de código. Se você compartilhar um pouco mais do código ao redor, o pessoal talvez consiga ajudar a revisar

  • wazoox: Ainda não aconteceu comigo, mas há dois dias encontrei isso nas profundezas de um código PHP em produção: uma função createUUID() que montava algo com cara de UUID cortando e colando o valor de md5(uniqid('', true))
    Não faço ideia de como esse horror ainda não mordeu nossa jugular

  • sedatk: O uuidjs/uuid tem um aviso de que clientes com geradores aleatórios determinísticos, como o Googlebot, podem gerar UUIDs duplicados
    Isso pode ser um problema para apps que esperam que UUIDs gerados no cliente sejam sempre únicos, então a estratégia recomendada é verificar duplicatas e falhar de forma elegante, ou desabilitar operações de escrita para clientes Googlebot: https://github.com/uuidjs/uuid/commit/91805f665c38b691ac2cbd...

  • xyzzy123: Já tive um teste de carga prolongado falhando por UUID duplicado em um sistema distribuído baseado em Linux
    Depois de muita investigação, descobrimos que era um bug de kernel, mais especificamente uma condição de corrida. Em sistema multiprocessado, se dois processos lessem /dev/random exatamente ao mesmo tempo, em casos muito raros, algo como uma em um milhão, podiam receber os mesmos bytes. Eu começaria olhando a inicialização do gerador aleatório

  • baq: Parece que a VM em execução virtualizou toda a entropia até ela sumir

  • glaslong: Preciso comprar umas lâmpadas de lava

  • 0xfffafaCrash: Fiquei curioso se o UUID foi gerado no frontend ou no backend. Se foi no frontend, em vez de problema de entropia eu apostaria na possibilidade de o código cliente ou a requisição ter sido manipulada para injetar um UUID já conhecido

  • latentframe: Uma das expressões mais perigosas em engenharia é estatisticamente impossível. Em escala suficiente, casos extremos deixam de ser teoria e viram evento operacional

  • 8organicbits: No ano passado escrevi sobre uma colisão real, incluindo a biblioteca envolvida: https://alexsci.com/blog/uuid-oops/
    Para UUID ter resistência a colisão, há muitas restrições que precisam ser seguidas com rigor, e neste caso parece bem provável que o problema esteja no gerador aleatório

  • nu11ptr: No fim das contas é problema de fonte de entropia. Por isso eu sempre gero e insiro dentro de um loop. Se houver colisão, dá para tratar de forma elegante

  • sbuttgereit: Não é “tecnicamente impossível”. É tecnicamente possível, sim. Com boa aleatoriedade, apenas extremamente, extremamente improvável; mas não existe nada em UUIDv4 que impeça tecnicamente a geração de valores duplicados

  • beardyw: Pode ser uma pergunta boba, mas não daria para anexar a data, nem que fosse em segundos em hexadecimal? Parece que adicionar só alguns bytes já garantiria que o que funciona hoje continue funcionando no futuro

    • flohofwoe: Basta usar outra variante de UUID que inclua dados de timestamp. Existem, por exemplo, v1 e v7, e também variantes que incluem endereço MAC
    • itsyonas: É só usar uuidv7
    • mittermayr: Sim, qualquer tipo de dado semialeatório adicional teria ajudado a impedir isso. Mas essa também era a ideia do UUIDv4. Eu achei que ele já tinha bastante aleatoriedade e tempo embutidos
  • mdavid626: Também pode haver outras explicações. Por exemplo, alguém pode ter mexido manualmente na requisição ou no banco

  • radial_symmetry: Já passei por algo assim uma vez e achei que eu estava enlouquecendo; ler os comentários aqui me tranquilizou

  • NKosmatos: Não é “tecnicamente impossível”. Não é impossível; é só extremamente, extremamente improvável. Acho que vale comprar um bilhete de loteria
    Sempre que vejo a palavra “improvável”, lembro de https://hitchhikers.fandom.com/wiki/Infinite_Improbability_D...

    • sebazzz: Na verdade você não deveria comprar loteria. Acontecerem tanto essa colisão quanto você ganhar na loteria seria ainda mais raro
    • rithdmc: É algo impossível de imaginar
  • sudb: Pela primeira vez senti a recompensa de ter escolhido CUID2 num dos meus projetos: https://github.com/paralleldrive/cuid2