Subject: | Encountering "Request has expired" EC2 errors |
I've encountered the EC2 error "Request has expired" several times now
when I've tried to stop EC2 instances. I googled around a bit and
learned that Amazon will report this error if the timestamp in the
message is more than 15 minutes different than what the current time is.
Looking through the code, I noticed that the message timestamp is set
at object creation using a default property as so:
has 'timestamp' => (
is => 'ro',
isa => 'Str',
required => 1,
default => sub {
my $ts = time2isoz();
chop($ts);
$ts .= '.000Z';
$ts =~ s/\s+/T/g;
return $ts;
}
);
I suspect this leads to a drift in the message timestamp leading to the
problem. I was easily able to reproduce the problem using the code below:
use Net::Amazon::EC2;
my $ec2 = Net::Amazon::EC2->new( AWSAccessKeyId => 'yourkey',
SecretAccessKey => 'yourpass',
retry => 1, );
die unless $ec2;
$ec2->create_security_group( GroupName => "Test", GroupDescription =>
'blank' );
# Start a instance
print "Starting instance ", $ec2->timestamp(), "\n";
$ec2->run_instances( ImageId => 'yourimage',
MinCount => 1, MaxCount => 1,
SecurityGroup => 'Test', );
print "Waiting...\n";
sleep( 60 * 16 ); # Wait more than 15 mins
print "Stopping...", $ec2->timestamp(), "\n";
my $id = $i->instances_set->[0]->instance_id;
my $res = $ec2->terminate_instances( InstanceId => $id);
if ( ref($res) ne 'ARRAY' && $res->isa('Net::Amazon::EC2::Errors') ) {
warn( "EC2 stop error: " . $_->message() ) foreach ( @{
$res->errors() } );
}
Reference:
http://developer.amazonwebservices.com/connect/thread.jspa?messageID=46724뚄