1 points par GN⁺ 2 시간 전 | 1 commentaires | Partager sur WhatsApp
  • La base de données a détecté aujourd’hui un UUID v4 en double, et la valeur existante était exactement identique à b6133fd6-70fe-4fe3-bed6-8ca8fc9386cd, déjà attribuée à un enregistrement ajouté en 2025
  • Le paquet utilisé est uuid sur npm, avec une génération effectuée via import { v4 as uuidv4 } from "uuid"; puis const document_id = uuidv4(); avant insertion dans la base de données
  • La base ne contient qu’environ 15 000 enregistrements, ce qui semble statistiquement impossible, et l’auteur demande si quelqu’un a déjà vécu la même chose

1 commentaires

 
GN⁺ 2 시간 전
Avis Hacker News
  • jandrewrogers : C’est étonnamment courant. La sécurité de l’UUIDv4 repose sur l’hypothèse qu’on dispose d’une source d’entropie de haute qualité, mais cette hypothèse est facilement invalidée par des défauts matériels, des bugs logiciels ordinaires ou une mauvaise compréhension de l’entropie par les développeurs
    Détecter qu’une source d’entropie est défaillante coûte assez cher, donc presque personne ne le fait, et au final on ne s’en rend compte qu’après une collision. C’est pourquoi l’UUIDv4 est explicitement interdit dans beaucoup de systèmes à haute fiabilité ou à fortes garanties

    • LocalH : C’est pour ça que CloudFlare a construit un mur de lampes à lave. Ce n’est pas tant que ce soit en soi une source d’entropie extraordinaire, mais ça rend la notion d’entropie et de génération aléatoire visible même pour ceux qui la comprennent mal
      Plus on a de sources d’entropie, mieux c’est, et une bonne partie d’entre elles devrait être non déterministe. Même dans un petit jeu, si on mélange dans la seed initiale des valeurs comme les coordonnées de la souris, l’intervalle entre les clics ou le nombre d’images avant d’appuyer sur le bouton de démarrage, il devient beaucoup plus difficile de prédire le résultat, même si on utilise ensuite un générateur pseudo-aléatoire en interne. Si CloudFlare utilisait moins de 100 sources d’entropie, je serais déçu
    • Groxx : J’ai déjà vu des doublons plausibles sur du matériel défectueux. Et avec certaines bibliothèques UUID, les motifs de doublons où la fin est remplie de zéros étaient aussi très fréquents
      Ça arrive quand on ne vérifie pas la valeur de retour du type « j’ai demandé N octets mais seulement 3 ont été renvoyés, donc il faut redemander les N-3 octets », comme dans l’ancien écosystème Go. Sur la plupart des machines ou systèmes d’exploitation, ça ne se produit pas, donc les gens ne vérifient pas, puis un jour ça explose en production avec des dizaines de milliers de collisions
    • thecloud : Je me demande quelles alternatives on utilise à l’UUIDv4 dans les systèmes à haute fiabilité
  • throwaway_19sz : C’est difficile à croire et assez drôle, mais c’est vrai. Il y a dix ans, un ami a rejoint une startup en hypercroissance comme CTO, une boîte avec environ 200 développeurs, et dès sa première semaine il a découvert qu’il existait un microservice dédié à la génération d’UUID
    Il y avait trois ingénieurs affectés à cet unique endpoint, plus même un DBA. Chaque équipe devait appeler ce service quand elle avait besoin d’un nouvel UUID « sûr » ; le service générait un UUID, vérifiait dans sa propre base s’il avait déjà été émis, l’insérait si ce n’était pas le cas, puis le renvoyait. Peut-être que c’était pour se rassurer, mais l’équipe avait aussi son propre tableau Kanban et ses propres sprints

    • Aurornis : Au début, j’ai travaillé dans des startups où les ressources étaient limitées, donc chaque création de chose ou embauche était mûrement réfléchie. À l’époque, cette histoire m’aurait semblé fictive
      Dans une startup rejointe plus tard, chaque nouvelle inquiétude imaginée par quelqu’un donnait naissance à un nouveau microservice et à une nouvelle équipe. L’objectif trimestriel consistait explicitement à augmenter la taille des équipes d’ingénierie, et des équipes de 3 ou 4 personnes se fabriquaient elles-mêmes du travail via leurs sprints et réunions de planification. J’ai proposé de déplacer des effectifs de projets stables vers des urgences, mais on m’a bloqué en disant que cela entrait en conflit avec des KPI imposant d’atteindre un certain nombre d’ingénieurs
    • wongarsu : Un jour, quelqu’un finira par optimiser ça avec un compteur global incrémental sur 128 bits à l’échelle de toute l’entreprise. Il suffit de lire la valeur courante, l’incrémenter de 1 et la distribuer, sans interroger une base de plus en plus grosse : O(1), rapide
      Pour la haute disponibilité et le déploiement mondial, on peut aussi sharder en donnant à chaque instance une plage d’ID dédiée. Il suffit de réserver quelques bits de poids fort pour l’ID du datacenter, puis quelques autres pour l’instance du générateur dans ce datacenter. Attends, j’ai l’impression d’avoir déjà vu ça quelque part… Je me demande si Twitter utilise toujours cette approche, ou s’ils ont fini par en changer
    • roryirvine : J’ai vu quelque chose de similaire, au fin fond d’une grande entreprise tech de la Silicon Valley. Sauf que la liste maître des UUID en usage se trouvait dans un service CMDB externe géré par un autre département, ce qui rendait le processus encore plus compliqué
      Chaque jour, on récupérait un dump de base pour vérifier les ID « temporaires », et ils ne devenaient « définitifs » qu’après soumission correcte au CMDB. Il y avait aussi des garde-fous pour empêcher qu’un ID temporaire passe en prod, ainsi qu’une procédure de recyclage des ID définitifs non utilisés. La dernière fois que j’en ai entendu parler, ils en étaient à leur 18e mois sur un projet prévu pour 6 mois visant à déplacer le cache de la base locale vers Zookeeper
  • CodesInChaos : En général, ça vient d’un générateur pseudo-aléatoire mal seedé. Savoir si l’UUID a été créé côté back-end ou côté front-end est important
    Le front-end est fondamentalement difficile à considérer comme fiable pour plusieurs raisons, y compris les collisions intentionnelles, donc il faut gérer les collisions. Le back-end peut, lui, être fiable. Par le passé, on voyait ça dans les VM, mais aujourd’hui ça devrait être réglé ; en revanche, si un processus fortement sandboxé utilise une voie de repli non sûre pour l’aléatoire, ça peut encore arriver. Un fork de processus ou de VM peut aussi produire des collisions par duplication d’état

    • danpalmer : J’ai entendu dire qu’une société d’analytics appelée Segment avait bâti tout son produit autour d’UUID générés dans le navigateur. Il y avait des collisions d’UUID navigateur un peu partout, et le produit semblait donc incapable de produire des données réellement exploitables. J’espère qu’ils ont corrigé ça depuis
  • kst : Ça me rappelle un passage de « Pro Git ». <https://git-scm.com/book/en/v2>
    L’exemple disait que si les 6,5 milliards d’humains sur Terre produisaient tous, chaque seconde, un volume de code équivalent à l’historique complet du noyau Linux et le poussaient dans un unique dépôt Git géant, il faudrait environ 2 ans pour atteindre 50 % de probabilité de collision d’objets SHA-1. J’aimais bien la formule disant qu’une collision naturelle SHA-1 était moins probable que le fait que tous les membres de l’équipe meurent la même nuit dans des attaques de loups sans lien entre elles. Les hashes SHA-1 ne sont pas des nombres aléatoires et ils font 160 bits, donc ce n’est pas la même chose qu’un UUIDv4, mais j’aime bien cette image des attaques de loups sans lien entre elles

    • mega_dean : Ça me rappelle cette page qui explique à quel point le nombre de permutations d’un jeu de cartes est immense : https://czep.net/weblog/52cards.html
      L’analogie dit en gros que si on faisait le tour de la Terre à l’équateur à raison d’un pas tous les milliards d’années, qu’à chaque tour on retirait une goutte d’eau du Pacifique, puis qu’une fois l’océan vide on empilait une feuille de papier, et qu’on répétait jusqu’à atteindre le Soleil, les trois premiers chiffres du minuteur de 52! secondes n’auraient toujours pas changé
    • swiftcoder : À l’inverse, une attaque par dictionnaire est assez réaliste, et comme peuvent en témoigner ceux qui ont commité ce fichier de test case dans Git sans réfléchir, c’est plutôt pénible
    • TacticalCoder : L’équipe Git ne travaille-t-elle pas activement à proposer, en plus de SHA-1, d’autres hashes comme SHA256 en option ?
  • e12e : Il y a une discussion connexe ici : https://github.com/uuidjs/uuid/issues/546
    On y lit par exemple que crypto.getRandomValues() testé dans googlebot était déterministe

    • D2OQZG8l5BI1S06 : C’est plausible. Mais je ne comprends pas pourquoi on générerait des UUID dans le navigateur. On dirait que ça va à l’encontre de l’objectif
  • adyavanapalli : Ce dont on parle est tellement rare qu’à cet instant précis, il est plus probable que toute la Terre soit détruite par un astéroïde

    • thomasmg : Ce n’est pas à ce point rare. J’avais fait le calcul : c’était plus rare qu’être frappé par une météorite, et j’avais ajouté cela, ainsi que le paradoxe des anniversaires, à l’article Wikipedia sur les UUID. Ça a été supprimé et remplacé il y a quelques années
      J’ai entendu parler d’une femme réellement frappée par une météorite mais qui a survécu avec une blessure à la jambe. Si une collision UUID s’est produite, il est de loin plus probable qu’elle vienne d’un bug logiciel ou d’un comportement anormal de l’ordinateur, voire d’un rayon cosmique. Les rayons cosmiques perturbent la mémoire ou le CPU plus souvent qu’on ne l’imagine
    • delichon : À peu près la probabilité qu’un astéroïde tape « … » puis clique sur le bouton pour ajouter un commentaire
    • spindump8930 : Comme d’autres l’ont dit, si on seed mal le générateur, c’est très fréquent. Pour filer l’analogie, c’est comme la probabilité d’être touché si la Terre était entourée d’une ceinture d’astéroïdes très dense façon science-fiction
  • juancn : Le générateur aléatoire n’est-il pas mal initialisé, ou manque-t-il d’entropie ? Si rien n’a été personnalisé, il utilise crypto.getRandomValues(rnds8), et getRandomValues ne précise pas de quantité minimale d’entropie

    • Hizonner : Il est presque certain que le générateur aléatoire est gravement défaillant, probablement à cause du seed. Il est aussi très probable qu’il casse la cryptographie en même temps
  • Geee : Selon l’interprétation des mondes multiples de la mécanique quantique, il doit exister quelque part une branche de l’univers où tous les UUID sont identiques. J’imagine ce que doivent penser les gens là-bas

    • suprjami : Ils doivent probablement prendre « cet UUID », puis lui ajouter un nombre incrémental à la fin pour le rendre unique. Problème résolu
    • BobaFloutist : Et il y a probablement encore plus d’univers où tous les UUID sont identiques sauf un seul. Ils n’ont juste pas encore utilisé celui-là. Ou alors des univers où seuls les deux premiers UUID sont uniques et tous les suivants sont l’un des deux
    • nyantaro1 : C’est pour ça que je n’aime pas trop l’approche à la Everett
  • mittermayr : Je suis tout à fait d’accord : ça n’a pas de sens. Mais si je devais deviner, je dirais qu’avant les UUIDv4 étaient générés sur le téléphone de l’utilisateur puis envoyés à la base, alors que celui qui est entré en collision ce matin a été généré sur un serveur Ubuntu
    Je ne sais pas exactement comment un UUIDv4 est généré ni si les caractéristiques de la machine génératrice influent sur l’algorithme, mais le seul changement qui me vienne à l’esprit est qu’avant ils étaient créés sur l’appareil et que depuis quelques mois ils le sont sur le serveur

    • AntiUSAbah : Ils faisaient générer l’UUID par l’utilisateur ? Honnêtement, il me semble plus probable qu’il y ait eu une implémentation bizarre qu’une vraie collision UUID. Je me demande comment la base a signalé cette collision
    • wongarsu : Si les deux UUID avaient été générés côté appareil, je pourrais comprendre le risque de collision. On a déjà vu des terminaux bas de gamme mal seeder leur générateur aléatoire, produisant des valeurs « aléatoires » identiques ; et c’est pire si la bibliothèque utilise un générateur bon marché au lieu d’un vrai générateur cryptographiquement sûr
      Mais côté serveur, surtout en 2026, ça ne devrait pas arriver. Autrefois, le seed aléatoire des VM posait problème, mais aujourd’hui ça devrait être moins le cas. Même si un seul des UUID a été mal généré, la probabilité qu’un UUID vraiment aléatoire tombe dessus reste extrêmement faible ; il faut donc probablement un problème des deux côtés
    • stubish : Une collision UUIDv4 est statistiquement extrêmement improbable. Une explication plus crédible est que les deux systèmes aient utilisé la même seed. Si la seed ne fait que quelques octets, la probabilité monte alors de l’ordre du milliardième au millionième
  • dweez : Il est temps de relire cet article amusant : https://jasonfantl.com/posts/Universal-Unique-IDs/
    Si on transformait tout l’univers en immense ordinateur dédié à générer des UUID jusqu’à la mort thermique, de combien de bits l’espace d’identifiants devrait-il disposer ?

    • CodeWriter23 : Tant qu’on y est, il faut aussi ceci : https://www.decisionproblem.com/paperclips/
    • ipaddr : L’exemple « est-ce que tu t’inquiètes que tous les humains sur Terre soient frappés par une météorite en ce moment ? » n’est peut-être pas le meilleur. Une seule météorite pourrait mettre fin au monde, et avec assez de temps, cette possibilité devient élevée
  • beejiu : Je me demande si les UUID sont générés côté client ou côté serveur. Si c’est côté client, ça peut venir de bots de crawl. Par exemple, Googlebot exécute le JavaScript avec un « aléatoire » déterministe

    • adzm : Lors d’un incident précédent avec ce package, on avait aussi conclu à l’absence d’aléatoire côté Googlebot : https://github.com/uuidjs/uuid/issues/546
    • AgentME : C’est très probablement soit ce cas-là, soit une ancienne version d’un package incapable d’utiliser correctement le générateur aléatoire système, soit un vieux polyfill cassé réimplémentant l’API crypto JS, soit une configuration d’hébergement étrange où plusieurs serveurs reprennent le même snapshot de VM et dupliquent l’état du générateur aléatoire
      Ce type d’explication est de plusieurs ordres de grandeur plus plausible qu’une vraie collision purement aléatoire
  • merlindru : Il y a de fortes chances que ce soit un problème de seed. Si vous pouvez prouver que ce n’est pas le cas, vous deviendrez peut-être un peu célèbre

  • erlkonig : Je répète toujours à mon équipe qu’avec suffisamment de données, des valeurs aléatoires peuvent finir par entrer en collision, et qu’à ce moment-là on découvre à quel point le logiciel est robuste
    Pourtant, beaucoup de développeurs expérimentés, de leads et même de CIO croient encore que c’est impossible et n’écrivent aucun code pour gérer ce cas. Un mauvais générateur aléatoire peut alors casser le système bien plus tôt que prévu, avec même une corruption concurrente sans détection ni régénération. Ça me rappelle les gens qui ne vérifient pas si malloc() a réussi. Je leur demande souvent : « si c’est impossible, n’est-ce pas qu’on utilise trop de bits ? »

  • leni536 : Ce n’est pas arrivé par hasard ; il y a un bug quelque part. À première vue, le package semble appeler crypto.randomUUID() du runtime JS, qui est censé être correctement seedé en permanence
    Un bug du runtime semble extrêmement improbable, mais on ne sait jamais. Je suis curieux de savoir quel runtime JS est utilisé

  • jbverschoor : La cause la plus plausible serait que le package aléatoire dont dépend uuid a été compromis récemment pour rendre les nombres « aléatoires » prévisibles. Dans ce cas, une attaque supply chain pourrait mettre en danger de nombreux projets liés à la cryptographie, au SSL ou à la téléphonie

    • jbverschoor : Il y a 3 semaines, dans uuid/src/rng.ts, le tableau aléatoire est devenu const. Tous les appels partagent désormais le même tableau aléatoire
      Les appels suivants écrasent donc l’aléatoire généré précédemment ; si vous avez créé quelque chose d’important, bonne chance. Avant, le code utilisait slice() pour faire une nouvelle copie. C’est peut-être involontaire, mais je ne vois pas comment ça a pu passer alors qu’un simple test générant deux nombres aléatoires et vérifiant qu’ils diffèrent n’aurait probablement même pas réussi
  • pif : Même avec une source d’entropie de haute qualité, on ne peut pas transformer un « probablement » en « nécessairement ». Si vous avez besoin d’une valeur difficile à deviner, regardez du côté de la cryptographie ; mais si vous avez besoin d’une unicité garantie, il faut la construire vous-même

  • athrowaway3z : Une règle empirique simple est de se demander si l’on peut mettre un timestamp dans l’ID en plus de l’aléatoire. Dans la plupart des cas, la réponse est oui, et UUIDv7 suffit
    Si vous avez étudié le problème assez en profondeur pour pouvoir démontrer que la fuite d’information n’est pas acceptable, félicitations : votre système est probablement assez complexe et assez lent pour utiliser un hash cryptographique fort, ou simplement UUIDv5 si vous n’avez pas envie de vous compliquer la vie

  • darqis : PostgreSQL 18 prend en charge uuidv7 nativement, et on peut simplement mettre unique et uuid7() comme valeur par défaut

  • tumdum_ : C’est un générateur pseudo-aléatoire mal seedé

  • serf : On parle d’environ 1 sur 4,72 × 10²⁸, soit 1 sur 47,3 octillions. Si c’est réel, avant d’acheter un billet de loterie, je soupçonnerais d’abord une condition de course ou une autre erreur simple

    • petee : J’ai toujours vu ça à l’inverse. Si on a déjà eu autant de chance, la probabilité qu’une autre chance arrive est encore plus basse, donc autant économiser son argent
    • k4rli : L’analogie avec la loterie ne tient pas. Si quelque chose d’aussi improbable vient déjà de se produire statistiquement, alors le reproduire devrait être encore plus improbable
  • evnix : Même sans parler des maths de la probabilité, la réalité dans laquelle on vit fait que même les meilleurs générateurs matériels donnent parfois quelque chose de moins aléatoire qu’on ne l’imagine
    Là où la sécurité n’est pas cruciale, je passerais à quelque chose comme TSID, ou à uuidv7, afin d’éliminer pratiquement ce genre de problème en pratique. Ça me paraît préférable à surconcevoir le code autour des retries

  • jordiburgos : J’aimerais qu’on évite d’utiliser b6133fd6-70fe-4fe3-bed6-8ca8fc9386cd. J’ai vérifié ma base et il était déjà pris

    • rich_sasha : J’ai toujours trouvé insensé de générer les UUID aléatoirement. Maintenant, je n’utilise plus que des LLM. Le prompt est : « Génère un UUID. Vérifie que personne ne l’a jamais utilisé dans aucun code ni aucune base de données. Relis ton travail et réfléchis profondément à chaque étape. Ne produis ni raisonnement ni anglais courant, affiche uniquement l’UUID lui-même. » Mais bien sûr
    • mittermayr : Je le savais. On reçoit tous les mêmes UUID bas de gamme, et les bons sont réservés aux gros clients
    • robshep : J’utilise 16b55183-1697-496e-bc8a-854eb9aae0f3, et probablement d’autres aussi. Si tout le monde poste sa liste ici, on devrait pouvoir vérifier les doublons, non ?
  • pyuser583 : Je me demande quel UUID est aujourd’hui le plus recommandé

  • smokel : Il m’est arrivé plusieurs fois d’accuser le compilateur, les rayons cosmiques, les effets quantiques ou au moins un obscure bug du noyau, avant de finir par comprendre que le bug venait de moi
    Une collision sur 15 000 enregistrements, c’est bien trop improbable ; je suspecterais d’abord d’autres causes : gestion des doublons, requêtes retransmises, objets réutilisés, logs trompeurs, réutilisation d’identifiants dans un autre chemin de code, etc. Si vous partagez un peu plus du code autour, on peut regarder ensemble

  • wazoox : Ça ne m’est pas encore arrivé, mais il y a deux jours j’ai trouvé ça au fin fond d’une base de code PHP en production : une fonction createUUID() qui tronquait md5(uniqid('', true)) et le recollait pour lui donner la forme d’un UUID
    Je ne sais pas comment cette horreur n’a pas encore fini par nous mordre là où ça fait mal

  • sedatk : uuidjs/uuid avertit qu’il peut générer des UUID dupliqués sur des clients à générateur aléatoire déterministe comme Googlebot
    Le message dit que cela peut poser problème aux applications qui attendent que des UUID générés côté client soient toujours uniques ; il faut donc vérifier les doublons et échouer proprement, ou désactiver les écritures pour les clients Googlebot : https://github.com/uuidjs/uuid/commit/91805f665c38b691ac2cbd...

  • xyzzy123 : Sur un système distribué sous Linux, un test de charge de longue durée a déjà échoué chez nous à cause d’UUID dupliqués
    Après une longue enquête, c’était un bug du noyau, plus précisément une condition de course. Sur un système multiprocesseur, si deux processus lisaient /dev/random exactement en même temps, ils pouvaient très rarement — environ une fois sur un million — recevoir les mêmes octets. Je commencerais par regarder l’initialisation du générateur aléatoire

  • baq : On dirait qu’une VM en cours d’exécution a virtualisé toute l’entropie jusqu’à la faire disparaître

  • glaslong : Il faut acheter des lampes à lave

  • 0xfffafaCrash : Je suis curieux de savoir si l’UUID a été généré côté front-end ou côté back-end. Si c’est côté front-end, je miserais moins sur un problème d’entropie que sur la possibilité que du code client ou une requête ait été manipulé pour injecter un UUID déjà connu

  • latentframe : L’une des phrases les plus dangereuses en ingénierie est statistiquement impossible. À suffisamment grande échelle, les cas extrêmes cessent d’être théoriques et deviennent des incidents de production

  • 8organicbits : J’ai écrit l’an dernier sur une vraie collision, avec la bibliothèque concernée : https://alexsci.com/blog/uuid-oops/
    Les UUID n’ont une résistance aux collisions que si l’on respecte strictement de nombreuses contraintes, et dans ce cas-ci il semble très probable que le problème vienne du générateur aléatoire

  • nu11ptr : Au fond, c’est un problème de source d’entropie. C’est pour ça que je génère et j’insère toujours dans une boucle. S’il y a collision, on peut la gérer proprement

  • sbuttgereit : Ce n’est pas « techniquement impossible ». C’est techniquement possible. Avec une bonne source d’aléatoire, c’est simplement très, très improbable, mais rien dans UUIDv4 n’empêche techniquement la génération de doublons

  • beardyw : Question peut-être bête, mais pourquoi ne pas ajouter la date, ne serait-ce qu’en secondes hexadécimales ? Avec juste quelques octets de plus, on aurait l’impression de garantir que ce qui est acceptable aujourd’hui le restera à l’avenir

    • flohofwoe : Il suffit d’utiliser une autre variante d’UUID qui inclut des données de timestamp. Par exemple v1 ou v7, et il existe aussi des variantes incluant une adresse MAC
    • itsyonas : Il suffit d’utiliser uuidv7
    • mittermayr : Oui, n’importe quelle donnée pseudo-aléatoire supplémentaire de ce genre aurait aidé à éviter ça. Mais c’est aussi un peu l’idée d’UUIDv4 : je pensais qu’il contenait déjà beaucoup d’aléatoire et de temps
  • mdavid626 : Il peut aussi y avoir d’autres explications. Par exemple, quelqu’un a pu bricoler la requête à la main ou intervenir dans la base

  • radial_symmetry : Ça m’est arrivé une fois et j’ai cru devenir fou, mais lire ces commentaires me rassure

  • NKosmatos : Ce n’est pas « techniquement impossible ». Ce n’est pas impossible ; c’est juste très, très improbable. Il faudrait peut-être acheter un billet de loterie
    Chaque fois que je vois le mot « improbable », je pense à https://hitchhikers.fandom.com/wiki/Infinite_Improbability_D...

    • sebazzz : En fait, il ne faut surtout pas acheter de billet de loterie. Que cette collision et un gain à la loterie se produisent tous deux serait encore plus rare
    • rithdmc : C’est inconcevable
  • sudb : Pour l’un de mes projets, j’ai pour la première fois l’impression que choisir CUID2 était vraiment une bonne idée : https://github.com/paralleldrive/cuid2