13 ms·
Ask HN: We just had an actual UUID v4 collision...
I know what you're thinking... and I still can't believe it, but...
This morning, our database flagged a duplicate UUID (v4). I checked, thinking it may have been a double-insert bug or something, but no.
The original UUID was from a record added in 2025 (about a year ago), and today the system inserted a new document with a fresh UUIDv4 and it came up with the exact same one:
b6133fd6-70fe-4fe3-bed6-8ca8fc9386cd
We're using this:
https://www.npmjs.com/package/uuid
I thought this is technically impossible, and it will never happen, and since we're not modifying the UUIDs in any way, I really wonder how that.... is possible!? We're literally only calling:
import { v4 as uuidv4 } from "uuid";
const document_id = uuidv4();
... and then insert into the database, that's it.
Additionally, the database only has about 15.000 records, and now one collision. Statistically... impossible.
Has that ever happened to anyone?! What in the...
- samdhar 5mo ago[flagged]
- uncircle 5mo agoStatistically speaking, does extremely unlikely mean impossible? If it were replicable I'd raise my eyebrow, otherwise it's fair game, no? As someone that enjoys the unterminable complaints about RNG in the video game scene, I would never trust any human's rationalization of random outcomes.
- nubg 5mo agoYou are replying to an AI bot
- harperlee 5mo agoWould be cool to have a plugin that shows % of bot per user, based on their history of comments.
- mschild 5mo ago> Statistically speaking, does extremely unlikely mean impossible? No, it means extremely unlikely. Collisions can occur, as op just found out, but the chances are so abysmally small that most people don't care. Any application I have worked on, I always had a pre-save check to see if the UUID was already present and generate a new one if it was. Don't think it ever triggered unless a bug was introduced somewhere but good practice anyway.
- nubg 5mo agoQuestion to fellow HNers, do you recognize that this comment was written by AI?
- deleted 5mo ago[deleted]
- uncircle 5mo agoI guess not, and I feel dirty now. I'm logging off for the day.
- mschild 5mo agoKind of. It reads a bit too much like tech support you'd get when asking one for help.
- prakka 5mo agoNo, to be honest. However, as soon as it was pointed out, I checked again and it made sense. In my opinion, these kind of intuitions have to grow over time. And every time it’s pointed out, you learn. So please, keep pointing it out :).
- tirutiru 5mo agoI did not. Post-conditioning by your comment and the other one,I can see some signs such attempting to be unusually comprehensive. The 'atoms in your liver' could be an awkward human trying to be poetic about scales. I still don't see idiomatic markers of AI so that's scary if your claim is correct.
- ssenssei 5mo agowhen it started going on about all the different cases in the second bullet point... yeah
- speedgoose 5mo agoYes, stupid comparison with atoms in the liver and a bullet list below? I stopped reading.
- deleted 5mo ago
- ashleyn 5mo agoThere could be a problem with the way the system generates entropy for randomness.
- serf 5mo ago1 in 4.72 × 10²⁸ 1 in 47.3 octillion. i'd be suspecting a race condition or some other naive mistake, otherwise id be stocking up on lottery tickets. (lol at the other user posting at the same time about the lottery ticket.. great minds and all that.)
- petee 5mo agoI've always looked at it the the other way - being that lucky would mean you have even less chance of something else lucky happening, good time to save your money
- k4rli 5mo agoThe lottery ticket part makes no sense. Statistically if such an improbable event just happened to him, then chance of it happening again should be even more improbable.
- jaccola 5mo agoThe chance of him winning the lottery is identical to before, however the reward if he wins is slightly greater. He would win the lottery money + he gets to tell people who don’t understand independence this incredible story!
- sowbug 5mo agoThis is probably (ha) a troll thread, but in case anyone here is among today's lucky (ha) 10,000, https://en.wikipedia.org/wiki/Independence_(probability_theory) https://en.wikipedia.org/wiki/Independence_(probability_theo...
- angoragoats 5mo agoNo, the events are independent. If you have a UUID collide, your chance of winning the lottery if you enter it is exactly the same as it was before the UUID collision.
- georgemcbay 5mo ago> If you have a UUID collide, your chance of winning the lottery is exactly the same as it was before the UUID collision. True, but only if you were already going to play the lottery anyway. If you don't normally play the lottery and the UUID collision combined with superstition is what enticed you to play, then the UUID collision will have raised your chances of winning the lottery from 0% to slightly higher than 0%.
- mittermayr 5mo agoI fully agree. It makes no sense. Yet... The only guesses I'm having is that we originally generated UUIDv4s on a user's phone before sending it to the database, and the UUID generated this morning that collided was created on an Ubuntu server. I don't fully know how UUIDv4s are generated and what (if anything) about the machine it's being generated on is part of the algorithm, but that's really the only change I can think of, that it used to generated on-device by users, and for many months now, has moved to being generated on server.
- stubish 5mo agoThe UUIDv4 collision is statistically extremely unlikely. What is more likely is both systems used the same seed. This might be just a handful of bytes, increasing the chance of collision to one in billions or even millions.
- tracker1 5mo agoThe shim for node:crypto in the browser is likely a weaker implementation in JS than the node implementation... you can cheat and use the browser itself to get a UUIDv4... function uuid4() { var temp_url = URL.createObjectURL(new Blob()); var uuid = temp_url.toString(); URL.revokeObjectURL(temp_url); return uuid.split(/[:\/]/g).pop().toLowerCase(); // remove prefixes }
- DarkUranium 5mo agoNo need for this dance in a modern browser: `crypto.randomUUID()` is a thing nowadays.
- AntiUSAbah 5mo agoYou let users generate a UUID? To be honest, the chance that you are doing something weird is probably higher than you experiencing a real UUID conflict. How did your database 'flag' that conflict?
- 5mo ago
- ESAM_C 5mo ago[dead]
- beardyw 5mo agoJust a stupid question, but why not append the date, even in seconds as hex. It's just a few bytes and would guarantee that everything OK now will be OK in the future?
- mittermayr 5mo agoyeah, any sort of additional semi-random data could've helped prevent this, I'm sure. That, however, is also kind of the idea of UUIDv4, it has lots of randomness and time built in already.
- flohofwoe 5mo agoUUID v4 consists of only random bits, no timestamp info.
- mittermayr 5mo agooh, interesting, I didn't know that and this could possibly be part of the problem perhaps depending on what's used as the seed.
- Lammy 5mo agoWrong, they have 122 random bits out of 128. The other six bits are to say “hello I am a UUIDv4”.
- beardyw 5mo agoBut surely hashing the date still allows for a future collision. Leaving the date as is means it will never collide after that one second has passed.
- kayodelycaon 5mo agoUUID 7 does not hash the date. It uses 48 bits to store a millisecond resolution timestamp. This allows you to sort uuids by time.
- toraway 5mo ago
- wg0 5mo agoWould the UUID v7 be more collision proof? Hard to say because it takes time into account but then the number of entropy bits are reduced hence the UUID generated exactly at the same time have more chance of a collusion because number of entropy bits are a much smaller space hence could result in collusions more easily. Thoughts?
- AntiUSAbah 5mo agoYou open up every millisecond a new block. Should be even more unlikely
- _kst_ 5mo agoUUID v7 relies on knowing what time it is. Speculation: The most likely scenario for a UUID v7 collision is if UUIDs are generated during a system boot sequence, before the system clock is set to the current time. It's always 1970 somewhere. There are still 62 random bits, and optionally another 12 random bits, but those too could be problematic if the system hasn't generated enough entropy yet.
- naikrovek 5mo agoThe chance of a UUIDv4 collision is very low, but it is never zero. If everything is done properly, then this is very likely the one and only time anyone involved in the telling or reading of this account will ever experience this.
- dalmo3 5mo agoClassic gamblers fallacy!
- jaccola 5mo agoIronically one of the few comments in this thread that isn’t necessarily the gamblers fallacy! The chance anyone involved saw or heard about the first one was near zero, now they’ve seen this one the chance they see another is still near zero (I.e unchanged).
- jordiburgos 5mo agoPlease, do not use b6133fd6-70fe-4fe3-bed6-8ca8fc9386cd, I checked my database and I was using it already.
- mittermayr 5mo agoI knew it, we're all getting the same cheap UUIDs and the good ones are reserved for the big dogs.
- robshep 5mo agoI'm using 16b55183-1697-496e-bc8a-854eb9aae0f3 and probably some more too. I suppose if we all post our list here, then we can all check for duplicates?
- mittermayr 5mo agoWe should all send our already-generated UUIDs to a shared database, we could just put it on Supabase with a shared username/password posted on HN, so we can all ensure that after generating a UUIDv4 locally, it's not used by anyone else. If it's in the database, we know it's taken. It's a super simple mechanism, check in common worldwide UUID database, if not in there, you can use it. Perhaps if we use a START TRANSACTION, we could ensure it's not taken as we insert. But that's all easy, I'll ask Claude to wire it up, no problem.
- broken-kebab 5mo agoBut then I will claim I have already used all the UUIDs in my spreadsheets, and my lawyer will send cease&desist letters to every database.
- adyavanapalli 5mo agoWhat you're talking about is so extremely rare that it's much more likely that the entire Earth is destroyed by an asteroid right this inst...
- delichon 5mo agoAbout as rare as an asteroid typing an ellipsis and clicking the add comment button.
- throw0101c 5mo agoWell, this joke dates back to (at least) the dial-up days where {#`%${%&`+'${`%& NO CARRIER
- xerox13ster 5mo agoThat’s just a result of jounce from localized gravity effects and atmospheric pressure disturbances in the moments before impact. Think the ultrasonic typing hacking scene in Pantheon combined with the keyboard bouncing due to rumbling.
- sebazzz 5mo agoWell it would be statistically even rarer for that UUID collision to happen and the earth to be destroyed by an asteroid.
- crazylogger 5mo agoFor a single database using UUIDs, yes, it's astronomically rare. But it's quite a different thing to say that no computer system on Earth has ever experienced a UUID collision. The number of systems out there is also astronomical.
- nathanmills 5mo ago>The number of systems out there is also astronomical. Not even close
- tumdum_ 5mo agoPoorly seeded prng.
- jdthedisciple 5mo agomost likely the culprit indeed
- nswango 5mo agoBut I used nonstandard nonces!
- glaslong 5mo agoBuy some lava lamps
- AndreyK1984 5mo agoWhy not to have timestamp-uuid instead ?
- dgellow 5mo agoHow confident are you that your machines clocks are in perfect sync? What about the risk of clock drift + correction, or hardware issues?
- croon 5mo agoNot GP, but: not confident. How confident would I be to avoid a (slightly lower entropy) UUID collision while also avoiding a clock desync landing on the exact same logged millisecond? Very, which is how confident I was about not encountering an UUID collision before this thread, so very++ I guess.
- kdps 5mo agoI get why sync of mutiple machines matters for ordering and causality, but why is it a problem for uniqueness?
- dgellow 5mo agoI just read UUIDv7, something I wasn't familiar with until now. That does address everything I had in mind yes. I assumed timestamp-uuid meant purely based on the timestamp precision, in which case you can get conflicts if you don't have a reliable clock across your system. But UUIDv7 looks pretty awesome: > What is a Version 7 UUID made from? > unix_ts_ms: 019e0c7bfe93 > ver: 7 > rand_a: 0b6 > var: b > rand_b: 55a99e023294673 So please ignore my previous comment :)
- ares623 5mo agoBuy a lottery ticket
- leni536 5mo agoIt's not happening by chance, there is a bug somewhere. From what I skimmed the package should just call to the js runtime's crypto.randomUUID(). I think it should always be properly seeded. I think it is extremely unlikely that the runtime has a bug here, but who knows? What js runtime do you use?
- not_math 5mo agoReminds me of some code I saw running in production. Every time we added a new entry, we were pulling all the UUIDs from this table, generating a new UUID, and checking for collisions up to 10 times.
- throwaway_19sz 5mo agoFunny story no one will believe, but it’s true. A good friend of mine joined a startup as CTO 10 years ago, high growth phase, maybe 200 devs… In his first week he discovered the company had a microservice for generating new UUIDs. One endpoint with its own dedicated team of 3 engineers …including a database guy (the plot thickens). Other teams were instructed to call this service every time they needed a new ‘safe’ UUID. My pal asked wtf. It turned out this service had its own DB to store every previously issued UUID. Requests were handled as follows: it would generate a UUID, then ‘validate’ it by checking its own database to ensure the newly generated UUID didn’t match any previously generated UUIDs, then insert it, then return it to the client. Peace of mind I guess. The team had its own kanban board and sprints.
- franktankbank 5mo agoWho has the balls to form that team? Were they disbanded?
- giancarlostoro 5mo agoI will gladly assume that this team was formed after several collisions with UUID's my assumption is that they had tremendous amount of data and enough revenue to justify all of this at least financially. I would have re-evaluated the UUID version used or if adopting Snowflakes would be better at some point.
- ryandvm 5mo agoPffft - they didn't need to store the whole UUID, just a hash. Dummies.
- NKosmatos 5mo ago> I thought this is technically impossible Actually it's not impossible, but very very improbable. P.S. You should play a lottery/powerball ticket P.P.S. Whenever I use the word improbable, the https://hitchhikers.fandom.com/wiki/Infinite_Improbability_Drive https://hitchhikers.fandom.com/wiki/Infinite_Improbability_D... comes in mind
- sebazzz 5mo ago> P.S. You should play a lottery/powerball ticket Actually, they should not. That collision and winning the lottery would be even rarer.
- lgeorget 5mo agoAssuming they are independent events, OP is not more nor less likely to win the lottery now that before running in the collision. I actually have more question if you claim the events in question are NOT independent!
- rithdmc 5mo agoInconceivable!
- sublinear 5mo ago> We're using this: https://www.npmjs.com/package/uuid https://www.npmjs.com/package/uuid Why? There's a built-in for this. https://nodejs.org/api/crypto.html#cryptorandomuuidoptions https://nodejs.org/api/crypto.html#cryptorandomuuidoptions
- OptionOfT 5mo agoThat's what the package uses. And if `crypto.randomUUID()` doesn't exist, it falls back to `crypto.getRandomValues()`, which per the documentation isn't AS strong: https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#:~:text=To%20guarantee%20enough,for%20cryptographic%20purposes. https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getR... So by using the package you actually lose visibility of cases where `crypto.randomUUID()` would fail.
- deleted 5mo ago[deleted]
- lyfeninja 5mo agoAlthough incredibly rare, it's not impossible so probably best to just plan for collisions. A simply retry should suffice. But I agree I feel like something is going on somewhere else ...
- Geee 5mo agoAccording to the many-worlds interpretation of quantum mechanics, there's bound to be one branch of universe where every UUID is the same. Can you imagine what those guys are thinking?
- zeeveener 5mo ago"Huh, this is just an identity function. Cool. Let's move on."
- nyantaro1 5mo agoThis is why I am not a fan of the Everett approach
- BobaFloutist 5mo agoNot only that, there's vastly more where every UUID except one is the same, but they never got to that one because they didn't ever use them. Or where the first two are unique, but every following one is one of the first two.
- beng-nl 5mo agoOne where all uuids are always different whenever the person who wrote the implementation tries it, regardless of computer. And whenever it’s someone else, always the same.
- suprjami 5mo agoThey probably just generate "the UUID" then add an increasing number on the end so it's unique. Problem solved.
- OutOfHere 5mo agoThis is why I prefer to use a random base32 string over UUID. At least you get a proper 128 bit entropy instead of just a 122 bit entropy as with UUIDv4. That's a 64x difference in collision probability. I always thought UUIDs were a toy, not for serious use. If you control the strings, you can even make a longer ID. Also, numerous applications that use a unique ID per record frequently need to check for ID collisions. I know I do for a short URL generator.
- juancn 5mo agoSomething off on how the RNG is initialized? Lack of entropy? If the rng is not customized it will use: const rnds8 = new Uint8Array(16); export default function rng() { return crypto.getRandomValues(rnds8); } getRandomValues doesn't specify a minimum amount of entropy.
- Hizonner 5mo agoIt's a near certainty that something is badly wrong with the RNG, and, yes, probably in how it's seeded. It's probably messing up the cryptography, too.
- Onavo 5mo agoBut defaults should be sane and safe. RNG isn't the sort of thing you want to be messing up. Every JS dev was taught that Math.random is not safe by default, but the crypto package is.
- deleted 5mo ago[deleted]
- merlindru 5mo agoGotta be a seeding issue. If it's not, and you can prove it, you're about to be a little famous probably :P
- deleted 5mo ago[deleted]
- baq 5mo agothe vm you're running on virtualized all the entropy away.
- Imustaskforhelp 5mo agoThis seems very likely to be the case. Something tangentially cool which is related: https://eu.mouser.com/new/leetronics/leetronics-infinite-noise-trng/ https://eu.mouser.com/new/leetronics/leetronics-infinite-noi...
- jbverschoor 5mo agoMost plausible cause: uuid package depends on some random number generator package, which has recently been compromised in order to make “random” numbers predictable. As a result, many crypto (ssl + currency) projects are compromised due to a supplychain attack.
- jbverschoor 5mo agoChanged 3 weeks ago: uuid/src/rng.ts : the random array is const. Every call will share the same random number. Subsequent call will update your old random code, so if you generated something important... good luck The old code used to do a slice() which creates a new copy. Might be unintentional. Although I have no idea how this would pass any tests, as you would think to test generating 2 randomnumbers and hope they are not the same.
- jbverschoor 5mo agoDidn't actually want to write a test myself.. but I miss Claudia confirmed it. Pretty concearning. Synchronous / serial calls: import rng from './rng'; const a = rng(); console.log('a after first call: ', Array.from(a)); const b = rng(); console.log('a after second call:', Array.from(a)); console.log('b after second call:', Array.from(b)); console.log('a === b (same reference)? ', a === b); console.log('a equals b (same contents)? ', a.every((v, i) => v === b[i])); output: a after first call: [ 101, 193, 125, 19, 142, 136, 181, 140, 209, 224, 176, 153, 179, 248, 246, 166 ] a after second call: [ 4, 29, 48, 215, 162, 60, 64, 23, 78, 137, 2, 186, 230, 249, 70, 224 ] b after second call: [ 4, 29, 48, 215, 162, 60, 64, 23, 78, 137, 2, 186, 230, 249, 70, 224 ] a === b (same reference)? true a equals b (same contents)? true and aynchronous calls: import rng from './rng'; async function getId() { const bytes = rng(); await new Promise(r => setTimeout(r, 0)); // yield to the event loop return Array.from(bytes); } const [id1, id2] = await Promise.all([getId(), getId()]); console.log('id1:', id1); console.log('id2:', id2); console.log('identical?', id1.every((v, i) => v === id2[i])); output: id1 captured: [ 61, 116, 151, 35, 153, 75, 105, 15, 59, 235, 162, 215, 224, 115, 31, 122 ] id2 captured: [ 13, 3, 84, 28, 22, 176, 160, 70, 67, 246, 1, 37, 38, 61, 171, 23 ] id1 after await: [ 13, 3, 84, 28, 22, 176, 160, 70, 67, 246, 1, 37, 38, 61, 171, 23 ] id2 after await: [ 13, 3, 84, 28, 22, 176, 160, 70, 67, 246, 1, 37, 38, 61, 171, 23 ] --- final id1: [ 13, 3, 84, 28, 22, 176, 160, 70, 67, 246, 1, 37, 38, 61, 171, 23 ] final id2: [ 13, 3, 84, 28, 22, 176, 160, 70, 67, 246, 1, 37, 38, 61, 171, 23 ] identical? true
- jandrewrogers 5mo agoThis is surprisingly common. The security of UUIDv4 is based on the assumption of a high-quality entropy source. This assumption is invalidated by hardware defects, normal software bugs, and developers not understanding what "high-quality entropy" actually means and that it is required for UUIDv4 to work as advertised. It is relatively expensive to detect when an entropy source is broken, so almost no one ever does. They find out when a collision happens, like you just did. UUIDv4 is explicitly forbidden for a lot of high-assurance and high-reliability software systems for this reason.
- thecloud 5mo agoThanks for the insight! Mind expanding on what alternatives are being used in high reliability systems instead of UUIDv4?
- lazide 5mo agoSequences, generally.
- tremon 5mo agoThat depends on your definition of high-availability. If high availability includes distributed writers, (global) sequences are not the best solution because generating unique sequence values requires synchronisation between all writers. In those cases, you might need to explicitly partition the ID space so that individual writers are guaranteed not to get in each others' hair.
- lazide 5mo agoThat is merely a sequence generation strategy.
- filcuk 5mo agoThe latest UUID (7?) Uses half random gen, half timestamp. This not only makes it sortable by creation, but would also make a collision like this impossible.
- dweez 5mo agoGood moment to revisit this fun article: https://jasonfantl.com/posts/Universal-Unique-IDs/ https://jasonfantl.com/posts/Universal-Unique-IDs/ If the entire universe were turned into a giant computer and did nothing but generate uuids until its heat death, how many bits would you need for the ID space?
- CodeWriter23 5mo agoIf you're gonna go there, this is obligatory https://www.decisionproblem.com/paperclips/ https://www.decisionproblem.com/paperclips/
- ipaddr 5mo ago"But are you worried that every human on Earth will be hit by a meteorite right now? That probability is also non-zero, yet it is so infinitesimally small that we treat it as an impossibility." This might be a bad example because one meteorite could take out the world and given enough time is likely to.
- sudb 5mo agoThis is first time I have experienced some vindication that choosing CUID2[1] for one of my projects was actually a good idea. 1. https://github.com/paralleldrive/cuid2 https://github.com/paralleldrive/cuid2
- sbuttgereit 5mo ago> I thought this is technically impossible No, very technically possible... though, with good randomness, very, very unlikely. But nothing technically prevents a UUIDv4 from generating a duplicate value.
- e12e 5mo agoSome discussion here: https://github.com/uuidjs/uuid/issues/546 https://github.com/uuidjs/uuid/issues/546 Eg: > FWIW, I just tested crypto.getRandomValues() behavior on googlebot and it is also deterministic(!)
- D2OQZG8l5BI1S06 5mo agoThat makes sense. I'm not sure why anybody would generate UUIDs in browsers though, it seems to defeat the purpose.
- danpalmer 5mo agoTell that to Segment. Hopefully they've fixed that, but they didn't seem to think it was a problem years ago (spoiler: it was a big problem).
- perlgeek 5mo agoWhen you do CQRS, you basically have to generate some form of unique identifier in the client. Why not a UUID in the browser?
- dylanhouli 5mo ago> I'm not sure why anybody would generate UUIDs in browsers though, it seems to defeat the purpose. How about for offline-first apps?
- shortercode 5mo agoFun thing about random is that these things happen. UUIDv7 is less prone to this as it includes both a time component and random. I’ve been using ULID in a few project which has similar attributes to uuidv7 but more space efficient.
- sqquima 5mo agoMeta, but if I had a question like this, I'd likely have asked on Twitter or Reddit first. I'll keep in mind using HN as an alternative Q&A site.
- danfritz 5mo agoAlways let your db generate uuids. On postgres this is easy since v18 it supports uuid v7! There is no need to set uuids through javascript or node imo
- hx8 5mo agoThere's plenty of reasons to set a unique identifier before database save, or to want a unique identifier that doesn't have a 1-to-1 relationship with your object. For example, in the idempotent kafka consumer pattern we set a unique ID in the header of every kafka message at the time of message publishing. We then have our consumers do a quick check of the ID against their data store to see if they have processed the message before or not. This way there is no impact if a consumer sees the same message twice. This allows us more flexibility during rebalancing events or replaying old offsets.
- Cantthink1029 5mo agoNot every application uses a DB you know, there are other reasons to use a UUID
- mdavid626 5mo agoOr there is some other explanation, eg. somebody messed with the request manually, or with the db.
- nu11ptr 5mo agoUltimately it comes down to your entropy source. I always generate and insert in a loop for this reason, if there is a collision, I therefore handle that gracefully.
- nozzlegear 5mo ago> I thought this is technically impossible, and it will never happen, In an eternal universe, even the most unlikely of events will happen an infinite number of times.
- beejiu 5mo agoAre your UUIDs generated client side or server side? If it's client side, it could be due to a crawling bot. Googlebot for example executes Javascript using deterministic "randomness".
- adzm 5mo agoGooglebot's lack of randomness was the conclusion of a previous incident for that package https://github.com/uuidjs/uuid/issues/546 https://github.com/uuidjs/uuid/issues/546
- AgentME 5mo agoYeah, the answer almost certainly has to be this, or that they were using an old version of the package which didn't use the system RNG correctly (the current version appears to do it correctly, but I didn't dive into older versions), or their project has loaded an old broken polyfill re-implementing the JS crypto API, or they were running this on a hosting setup that does something jank like resuming the same VM snapshot with its RNG state on multiple servers. This category of explanation is many orders of magnitude more likely than a true random collision.
- MagicMoonlight 5mo agoThis is why it’s stupid to assume a randomly generated ID is unique just because it is random.
- CodesInChaos 5mo agoThis is usually caused by an insufficently seeded PRNG. Are you generating the UUID in the backend, or the frontend? Frontend is fundamentally unreliable for many reasons, including deliberate collisions. So if that case you'll need to handle collisions somehow. Though you can still engineer around common sources of collisions, the specifics depend on the environment. On the other hand making a backend reliable is feasible. What kind of environment is your code running in? Historically VMs sometimes suffered from this problem, though this should be solved nowadays. Heavily sandboxed processes might still run into this, if the RNG library uses an unsafe fallback. Forking processes or VMs can cause state duplication and thus collisions.
- danpalmer 5mo agoI remember hearing about Segment (analytics company) had their entire product based around UUIDs generated in web browsers. There were collisions all over the place, the product was seemingly incapable of producing useful data at a fundamental level because of it. Hopefully they've fixed that now.
- dist-epoch 5mo agoIt's much more likely that you hit an "impossible bug" due to a bit flip somewhere. Imagine the database having the old UUID in a memory buffer due to a recent index scan, and a bit flip happened somewhere in the logic which basically copied the old UUID into the memory location of the new UUID, or some buffer addresses got swapped, or the operation which allocated the new UUID received a memory buffer containing the old one, and due to a bit flip the memcpy operation was skipped, or something along that line. Facebook wrote extensively about this, stuff like "if (false) {do_x(); )" and do_x being called. For example their critical RocksDB kv store has extensive redundant protections to defend against such "impossible bugs".
- rglover 5mo agoA check inside the generator function is the best way I've found to avoid this. Wrap uuid or whatever random generator with a check against an ID cache. If it already exists, just run the generator recursively.
- dividendflow 5mo ago[flagged]
- _kst_ 5mo agoThis reminds me of a passage from the book "Pro Git". <https://git-scm.com/book/en/v2 https://git-scm.com/book/en/v2> "Here’s an example to give you an idea of what it would take to get a SHA-1 collision. If all 6.5 billion humans on Earth were programming, and every second, each one was producing code that was the equivalent of the entire Linux kernel history (6.5 million Git objects) and pushing it into one enormous Git repository, it would take roughly 2 years until that repository contained enough objects to have a 50% probability of a single SHA-1 object collision. Thus, an organic SHA-1 collision is less likely than every member of your programming team being attacked and killed by wolves in unrelated incidents on the same night." Deliberate collisions are addressed in the following paragraph. SHA-1 hashes are not random, so the issue of poor pseudo-random number generation doesn't apply as it does to uuidv4. And SHA-1 hashes are 160 bits, vs. 128 for uuidv4. But I love the idea of unrelated wolf attacks.
- swiftcoder 5mo agoOn the other hand, it turns out that pre-image attacks are quite feasible, and as several people who have thoughtlessly committed the pre-image attack test case files to git can attest… quite problematic
- TacticalCoder 5mo agoHasn't the Git team been hard at work to optionally offer other hashes, like SHA256, in addition to SHA-1?
- ted_dunning 5mo agoThey have been not at work on doing that.
- mega_dean 5mo agoReminds me of this page with an example for understanding how many permutations there are for a shuffled deck of cards: https://czep.net/weblog/52cards.html https://czep.net/weblog/52cards.html > So, just how large is it? Let's try to wrap our puny human brains around the magnitude of this number with a fun little theoretical exercise. Start a timer that will count down the number of seconds from 52! to 0. We're going to see how much fun we can have before the timer counts down all the way. Shall we play a game? > Start by picking your favorite spot on the equator. You're going to walk around the world along the equator, but take a very leisurely pace of one step every billion years. The equatorial circumference of the Earth is 40,075,017 meters. Make sure to pack a deck of playing cards, so you can get in a few trillion hands of solitaire between steps. After you complete your round the world trip, remove one drop of water from the Pacific Ocean. Now do the same thing again: walk around the world at one billion years per step, removing one drop of water from the Pacific Ocean each time you circle the globe. The Pacific Ocean contains 707.6 million cubic kilometers of water. Continue until the ocean is empty. When it is, take one sheet of paper and place it flat on the ground. Now, fill the ocean back up and start the entire process all over again, adding a sheet of paper to the stack each time you’ve emptied the ocean. Do this until the stack of paper reaches from the Earth to the Sun. Take a glance at the timer, you will see that the three left-most digits haven’t even changed. You still have 8.063e67 more seconds to go. 1 Astronomical Unit, the distance from the Earth to the Sun, is defined as 149,597,870.691 kilometers. So, take the stack of papers down and do it all over again. One thousand times more. Unfortunately, that still won’t do it. There are still more than 5.385e67 seconds remaining. You’re just about a third of the way done.
- zuzululu 5mo agojust uuidv5
- nhumrich 5mo ago> technically impossible Not at all! Just very unlikely. It's about odds and statistics. Not physics.
- ASalazarMX 5mo agoThis undersells the word unlikely. It is very, very, very, very unlikely.
- kittikitti 5mo agoAlmost all pseudo-random number generators are absolute garbage. They need you believe they work because the NSA needs backdoors and to foolproof ransomware attacks. This isn't surprising at all to me.
- smokel 5mo agoMultiple times have I blamed compilers, cosmic rays, quantum effects, or at the very least an obscure kernel bug, before realizing that I was the source of a bug. A collision at 15,000 records is so unlikely that I would first suspect something else. Duplicate processing, replayed requests, reused objects, misleading logs, or another code path reusing the identifier. Could you share a bit more of the surrounding code so we can check?
- coldtea 5mo agoWere the chances than an npm package is crap factored in?
- Lammy 5mo ago> I thought this is technically impossible, and it will never happen I always hated this meme/mindset, because if you dig in to the history of them you'll see that their original purpose was to collide. They were labels to identify messages in Apollo's distributed computing architecture. UID and later UUIDs were a reversible way to mark an intersection point between two dimensions. Any two nodes in a distributed system would generate the same UID/UUID for the same two inputs, and a recipient of an identified message could reverse the identifier back into the original components. They were designed as labels for ephemeral messages so the two dimensions were time and hardware ID (originally Apollo serial number, later 802.3 hwaddress etc). I think a lot of the confusion can be traced to the very earliest AEGIS implementation where the Apollo engineers started using “canned” (their term, i.e. static or well-known) UIDs to identify filesystems. Over time the popular usage of UUID fully shifted from ephemeral identifiers where duplicates were intentional toward canned identifiers where duplicates were unwanted and the two dimensions were random-and-also-random.
- 8organicbits 5mo agoI wrote about real world collisions, including that particular library last year (https://alexsci.com/blog/uuid-oops/ https://alexsci.com/blog/uuid-oops/). There are a bunch of constraints that must be strictly held for UUIDs to be collision resistant, I'd guess there is a problem with your random number generator.
- zie 5mo agoYou forgot to use https://www.random.org/ https://www.random.org/ as your source of randomness :)
- sedatk 5mo ago> Duplicate UUIDs (Googlebot) > This module may generate duplicate UUIDs when run in clients with deterministic random number generators, such as Googlebot crawlers. This can cause problems for apps that expect client-generated UUIDs to always be unique. Developers should be prepared for this and have a strategy for dealing with possible collisions, such as: > - Check for duplicate UUIDs, fail gracefully > - Disable write operations for Googlebot clients https://github.com/uuidjs/uuid/commit/91805f665c38b691ac2cbda56a99231432b00a1a#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5R23-R421 https://github.com/uuidjs/uuid/commit/91805f665c38b691ac2cbd...
- BugsJustFindMe 5mo agoThis is like one of the hardest things for people to understand. Even the best randomness guarantees fuck all. Entropy-based IDs are collision-resistant not collision-proof.
- QuercusMax 5mo agoI lost all confidence in the infallability of software RNG when I was working on an assignment for Data Structures a million years ago (2000?). The assignment was simple: simulate a 2D random walk where you randomly go NSEW, and run 100 cases, collecting stats as to how long it takes to return to the origin. Super easy assignment, wrote it up probably in C++ (maybe just C?), and ran it on my linux box (probably Debian potato). It finished super quick and gave me an average of like 5.6 steps to return to the origin or something. Cool! I copied it over to my account on the department's HP-UX machines where I was supposed to run and submit it to my instructor. Compiled fine. And then it... just ran forever. I was doing rand() % 4 or something, and the HP-SUX RNG had crazy bias in its last 2 bits, and it just walked away forever, never returning to the origin. Well crap! Got an A for my writeup, though!
- DarkUranium 5mo agoI mean ... rand() is notoriously bad, plenty of actually good options out there. Even back in 1990s.
- deleted 5mo ago[deleted]
- radial_symmetry 5mo agoGlad to be reading the comments here because I also had this happen to me once and thought I must have been going insane.
- 0xfffafaCrash 5mo agoIs the uuid generated in the frontend or backend? If frontend, I’d wager the likeliest explanation is that the client code or request was messed with to inject a previously known uuid rather than an entropy issue.
- xyzzy123 5mo agoI had dup uuids causing soak test failures in a Linux based distributed system. After long investigation it turned out there was a kernel bug (race condition) that meant two processes on MP system reading from /dev/random at the same could (very rarely, like 1 in a million) get the same bytes when reading the device. I'd look at rng initialisation first.
- latentframe 5mo agoOne of the most dangerous words in engineering is “statisticaly impossible” At enough scale edge cases stop to be theoretical and start become production events.
- pif 5mo agoAll the comments I've been able to read are missing the elephant in the room: no high-quality entropy source can turn a "should" into a "must". If you want something that is difficult to guess, ask the cryptography guys. But if you need something that is -_guaranteed_ unique, you must build it yourself.
- evnix 5mo agoAll the probability mathematics aside, the real world we live in is probably a lot less random even with the best hardware random number generators. I've moved on to something like TSID(where security isn't a factor) or uuidv7 to make sure this never really occurs in practice rather than over engineering the code with retries.
- athrowaway3z 5mo agoThe rule of thumb is simple: Consider if your ID can contain a timestamp besides a random value. The answer is usually yes. UUIDv7 is fine. If you've spend the time to really work through the whole problem and have written down a proof how that leads to unacceptable info leak: Congratulations your system is complex and slow enough that you might as well take a strong cryptographic hash or UUIDv5 if you're lazy.
- byteflow 5mo agoThat's insane..
- pyuser583 5mo agoWhat’s the prefered uuid these days?
- erlkonig 5mo agoI keep telling the dev teams I'm on that with enough data points, all those random numbers will (probably) eventually collide, and *then* we'll see how robust their software really is. At least your database flagged it, and hopefully nothing major exploded. And yet, plenty of experienced devs, including team leads and CIOs, are convinced it's impossible. As in, they absolutely don't write code to deal with the condition. So a bad RNG can randomly destroy the system far sooner than expected at any time, and it won't be noticed, caught, re-genned, or anything, with concurrent corruption being entirely possible. They're fine with it. I feel like these are the same guys who don't check to see if malloc() succeeds. I like to ask them, "If it's impossible, you're using too many bits, right?". I haven't talked any of them into hedging with a brownian motion detector, or a lava lamp or something for better randomness yet, but I'm still trying.
- darqis 5mo agopg 18 supports uuidv7 natively and your default should be unique and uuid7()
- wazoox 5mo agoThis didn't happen to me... yet. Here's what I found 2 days ago deep in a production PHP codebase: private static function createUUID(){ $md5 = md5(uniqid('', true)); return substr($md5, 0, 8 ) . '-' . substr($md5, 8, 4) . '-' . substr($md5, 12, 4) . '-' . substr($md5, 16, 4) . '-' . substr($md5, 20, 12); } Holy cow, how didn't this horror come and bite us in the juicy parts ? I don't know.
- timbritt 5mo agoWhy is nobody asking why the database wasn’t configured to enforce uniqueness on this column? This should have been a log discovery.
- deleted 5mo ago[deleted]
- deleted 5mo ago[deleted]
- swah 5mo agoconst blacklisted = ['b6133fd6-70fe-4fe3-bed6-8ca8fc9386cd'];
- pedro_ascenso 5mo ago[dead]
- jabeer 5mo agoWould love feedback on my HTML-to-PDF API — pdfkitt.dev
- sullof 5mo ago[flagged]
- unchainedsky90 5mo ago[dead]
- abhishekiaex 5mo agoSo, what the solution folks? I am also using the same in our network system.
- arslantoor 5mo agoBTW, it never happened to me, I have been working for more than 7 years as a developer maintaining over 1M plus records, but the twist is that we used to generate UUID by timestamps, which is now automatically handled by uuidv7, where the first half is our timestamps and the second half random number, so collisions never happen. In your case, you must be shifted to UUIDv7 without making any change, or just generate using a timestamp But yeah, collision is expected in random generation; a UUIDv4 is a 128-bit number. If you subtract the bits used to specify the version and variant, you are left with 122 bits of pure randomness.That means there are $2^{122}$ possible combinations, where each 100 combination has chances of collision by 50%
- ovo101 5mo ago[flagged]