The problem is that your %hash is valid as Perl will just store the last value for key "one". Perhaps this would work with Hash::MultiValue? I am thinking of something like this:
use strict;
use warnings;
use Hash::MultiValue;
use 5.012;
my $mhash = Hash::MultiValue->new(
"one" => "3",
"two" => "2",
"two" => "1"
);
die "Duplicate key detected for \%hash" if grep { my @a = $mhash->get_
+all($_); @a > 1 } $mhash->keys;
print "We're good!";
I have not used it in anger myself but it would seem as though it would work for what you want!