AWS Error Message: InvalidInstanceID.NotFound - java

I'm trying to start a Amazon EC2 cloud machine with [startInstance][2] method using aws-sdk in Java. My code is as follows.
public String startInstance(String instanceId) throws Exception {
List<String> instanceIds = new ArrayList<String>();
instanceIds.add(instanceId);
StartInstancesRequest startRequest = new StartInstancesRequest(
instanceIds);
startRequest.setRequestCredentials(getCredentials());
StartInstancesResult startResult = ec2.startInstances(startRequest);
List<InstanceStateChange> stateChangeList = startResult
.getStartingInstances();
log.trace("Starting instance '{}':", instanceId);
// Wait for the instance to be started
return waitForTransitionCompletion(stateChangeList, "running",
instanceId);
}
When I run the above code, i'm getting the following AWS error:
Status Code: 400, AWS Request ID: e1bd4795-a609-44d1-9e80-43611e80006b, AWS Erro
r Code: InvalidInstanceID.NotFound, AWS Error Message: The instance ID 'i-2b97ac
2f' does not exist
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpCli
ent.java:538)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.ja
va:283)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:168
)
at com.amazonaws.services.ec2.AmazonEC2Client.invoke(AmazonEC2Client.jav
a:5208)
at com.amazonaws.services.ec2.AmazonEC2Client.startInstances(AmazonEC2Cl
ient.java:2426)

AWS Error Message: The instance ID 'i-2b97ac2f' does not exist
You'll have to take the AWS response for granted here, i.e. the instance does not exist ;)
But seriously: Presumably you have already verified that you are actually running an instance with this ID in your account? Then this is most likely caused by targeting the wrong API endpoint, insofar an instance ID is only valid within a specific region (if not specified, the region defaults to 'us-east-1', see below).
In this case you need to specify the actual instance region via the setEndpoint() method of the AmazonEC2Client object within the apparently global ec2 variable before calling startInstances().
There are some examples regarding Using Regions with the AWS SDKs and all currently available AWS regional endpoint URLs are listed in Regions and Endpoints, specifically the Amazon Elastic Compute Cloud (EC2) defaults to 'us-east-1':
If you just specify the general endpoint (ec2.amazonaws.com), Amazon
EC2 directs your request to the us-east-1 endpoint.

We run a service (Qubole) that frequently spawns and then tags (and in some cases terminates) AWS instances immediately.
We have found that Amazon will, every once in a while, claim an instanceid as invalid - even though it has just created it. Retrying a few times with some sleep time thrown in usually solves the problem. Even a total retry interval of 15s proved insufficient in rare cases.
This experience comes from the useast region. We do not make api calls to different regions - so that is not an explanation. More likely - this is the infamous eventual consistency at work - where AWS is unable to provide read-after-write consistency for these api calls.

I am using the AWS ruby api and I noticed the same issue when creating an AMI image and its status is pending when I look in the AWS console but after a while the image is available for use.
Here is my script
image = ec2.images.create(:name => image_name, :instance_id => ami_id, :description => desc)
sleep 5 while image.state != :available
I sleep for about 5 sec for image to be in available but I get the error saying that the "AWS Error Message: InvalidInstanceID.NotFound". During my testing this is fine but most of the time this seems to be failing during continuous integration builds.

InvalidInstanceID.NotFound means the specified instance does not exist.
Ensure that you have indicated the region in which the instance is located, if it's not in the default region.
This error may occur because the ID of a recently created instance has not propagated through the system. For more information, see Eventual Consistency.

Related

Why am I getting error creating object in Minio?

I'm trying to create an object in Minio. Sometimes it works and sometimes no.
When I execute :
minioClient.makeBucket(bucketName); // bucketName es a random unique string
I donĀ“t get error, but if If ask Minio if bucket exists:
minioClient.bucketExists(bucketName)
it returns false
After that, If I try to launch once again minioClient.makeBucket(bucketName) because minioClient.bucketExists(bucketName) is returning false, then I get this error (simplified):
BucketAlreadyOwnedByYou
So that, when I get previous error, I try to create object in Minio :
minioClient.putObject(bucketName, objectName, is,null,customMetaData,null, null ); // is is an InputStream of the file I want to store in Minio
But I get this error, saying bucket does not exist;
ErrorResponse(code=NoSuchBucket, message=The specified bucket does not exist, bucketName=888bf891-064f-4270-b0f0-85514c0eae02, objectName=L7aEmF8Ppk, resource=/888bf891-064f-4270-b0f0-85514c0eae02/L7aEmF8Ppk, requestId=16733C7840E6854D, hostId=null)
Any help will be appreciated.
I'm using version 6.0.13 of Minio Java API
This not how MinIO should behave. I have only seen this error where it was either a programming error or a setup error.
When it is a setup error, the root problem is that instead of creating 1 server pool with 4 distributed nodes, people have created 4 server pools each with a single node. This means that when your application gets load balanced, it will sometimes hit the server pool where you created the bucket and sometimes not.
Another cause can be an non-consistent filesystem used as backend. For example NFS with certain settings can have behavior like this. The recommended filesystem is XFS.
Without knowing more about your setup I cannot tell you which one it is.

How to resolve 'protocol must not be null' for CopySnapshotRequest across regions

I am attempting to move an EC2 snapshot from one region to another.
When creating a basic Ec2 snapshot copy and copying it to a second Region I get the error protocol must not be null. It appears that the host is also null when you get to the point in the code that will require a host. From my understanding I do not need to provide the protocol (http/https) or the host details when copying a snapshot the is NOT encrypted. It appears that the AWS code should do this behind the scenes.
Off the top of my head this seems like an aws issue but there is not much feedback on the AWS SDK for Java V2 yet as I have checked here as well as github.
Program exception:
java.lang.NullPointerException: protocol must not be null
I have tried adding the destinationRegion to the builder but that also results in the same error.
Execution environment is Amazon Java 11.0.3
I have tried with software.amazon.awssdk versions 2.7.11 all the way through 2.7.29
Basic code snippet
String amazonAccessKeyId = "amazonAccessKeyId";
String amazonSecretKeyId = "amazonSecretKeyId";
String baseRegionName = "baseRegionName"; // Region.AP_NORTHEAST_1.id(); or where ever your snapshot is located
String remoteRegionName = "remoteRegionName "; // Region.AP_NORTHEAST_1.id(); or where ever your snapshot is located
String snapshotId = "snapshotId"; // You will need a snapshot to work with this code
// Setup AWS remote client with credentials
AwsCredentials credentials = AwsBasicCredentials.create(amazonAccessKeyId, amazonSecretKeyId);
Ec2Client amazonEc2RemoteRegionClient = Ec2Client.builder()
.region(Region.of(remoteRegionName))
.credentialsProvider(StaticCredentialsProvider.create(credentials))
.build();
// Setup request
CopySnapshotRequest request = CopySnapshotRequest.builder()
.sourceRegion(Region.of(baseRegionName).id())
.sourceSnapshotId(snapshotId)
.description("Foo Bar Testing...")
.build();
// Invoke copy from remote region to pull in snapshot from source/default region
// This is the line in question
CopySnapshotResponse result = amazonEc2RemoteRegionClient.copySnapshot(request);
Stack trace follows
java.lang.NullPointerException: protocol must not be null.
at software.amazon.awssdk.utils.Validate.paramNotNull(Validate.java:117)
at software.amazon.awssdk.http.DefaultSdkHttpFullRequest.standardizeProtocol(DefaultSdkHttpFullRequest.java:63)
at software.amazon.awssdk.http.DefaultSdkHttpFullRequest.<init>(DefaultSdkHttpFullRequest.java:52)
at software.amazon.awssdk.http.DefaultSdkHttpFullRequest.<init>(DefaultSdkHttpFullRequest.java:41)
at software.amazon.awssdk.http.DefaultSdkHttpFullRequest$Builder.build(DefaultSdkHttpFullRequest.java:331)
at software.amazon.awssdk.http.DefaultSdkHttpFullRequest$Builder.build(DefaultSdkHttpFullRequest.java:170)
at software.amazon.awssdk.services.ec2.transform.internal.GeneratePreSignUrlInterceptor.modifyHttpRequest(GeneratePreSignUrlInterceptor.java:102)
at software.amazon.awssdk.core.interceptor.ExecutionInterceptorChain.modifyHttpRequestAndHttpContent(ExecutionInterceptorChain.java:99)
at software.amazon.awssdk.core.client.handler.BaseClientHandler.runModifyHttpRequestAndHttpContentInterceptors(BaseClientHandler.java:123)
at software.amazon.awssdk.core.client.handler.BaseClientHandler.finalizeSdkHttpFullRequest(BaseClientHandler.java:68)
at software.amazon.awssdk.core.client.handler.BaseSyncClientHandler.execute(BaseSyncClientHandler.java:106)
at software.amazon.awssdk.core.client.handler.BaseSyncClientHandler.execute(BaseSyncClientHandler.java:73)
at software.amazon.awssdk.core.client.handler.SdkSyncClientHandler.execute(SdkSyncClientHandler.java:44)
at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.execute(AwsSyncClientHandler.java:55)
at software.amazon.awssdk.services.ec2.DefaultEc2Client.copySnapshot(DefaultEc2Client.java:2808)
I expect the snapshot to be copied to the new region specified, without error, and not encrypted.
As a side note I have submitted this to Amazon through my support system and I am awaiting a response from them. I will update this post once they respond to my request.
copySnapshot
sdk error,builder with presignedUrl can skip it

AWS ElasticSearch 2.3 Java HTTP bulk API

I'm attampting to use a bulk HTTP api in Java on AWS ElasticSearch 2.3.
When I use a rest client for teh bulk load, I get the following error:
504 GATEWAY_TIMEOUT
When I run it as Lambda in Java, for HTTP Posts, I get:
{
"errorMessage": "2017-01-09T19:05:32.925Z 8e8164a7-d69e-11e6-8954-f3ac8e70b5be Task timed out after 15.00 seconds"
}
Through testing I noticed the bulk API doesn't work these with these settings:
"number_of_shards" : 5,
"number_of_replicas" : 5
When shards and replicas are set to 1, I can do a bulk load no problem.
I have tried using this setting to allow for my bulk load as well:
"refresh_interval" : -1
but so far it made no impact at all. In Java Lambda, I load my data as an InputStream from S3 location.
What are my options at this point for Java HTTP?
Is there anything else in index settings I could try?
Is there anything else in AWS access policy I could try?
Thank you for your time.
1Edit:
I also have tried these params: _bulk?action.write_consistency=one&refresh But makes no difference so far.
2Edit:
here is what made my bulk load work - set consistency param (I did NOT need to set refresh_interval):
URIBuilder uriBuilder = new URIBuilder(myuri);
uriBuilder = uriBuilder.addParameter("consistency", "one");
HttpPost post = new HttpPost(uriBuilder.build());
HttpEntity entity = new InputStreamEntity(myInputStream);
post.setEntity(entity);
From my experience, the issue can occur when your index replication settings can not be satisfied by your cluster. This happens either during a network partition, or if you simply set a replication requirement that can not be satisfied by your physical cluster.
In my case, this happens when I apply my production settings (number_of_replicas : 3) to my development cluster (which is single node cluster).
Your two solutions (setting the replica's to 1 Or setting your consistency to 1) resolve this issue because they allow Elastic to continue the bulk index w/o waiting for additional replica's to come online.
Elastic Search probably could have a more intuitive message on failure, maybe they do in Elastic 5.
Setting your cluster to a single

JAVA AWS Machine Learning API to enable Realtime prediction

Can someone help me with name of api which enables realtime prediction of a model. Please note that i am not requesting for RealtimeEndpointRequest object. i have gone through the entire documentation of AWS Machine Learning SDK but haven't found any thing.
Edit 1 :
This is the code that i have used -
CreateRealTimePrediction createRealTimePrediction ;
CreateRealtimeEndpointRequest createRealtimeEndPointReq;
CreateRealtimeEndpointResult createRealtimeEndPointRes;
PredictRequest predReq;
String mlModelId="ml-Lkqmcs8cM2W";
createRealtimeEndPointReq.setMLModelId(mlModelId);
PredictResult predRes = null;
Map<String,String> record=null;
// assume i have set a record in the Map.
createRealtimeEndPointRes = amlClient.createRealtimeEndpoint(createRealtimeEndPointReq);
String predictEndpoint=createRealtimeEndPointRes.getRealtimeEndpointInfo().getEndpointUrl();
predReq= new PredictRequest();
predReq.setMLModelId(mlModelId);
for (int i=0;i<recordKeys.length;i++){
record.put(recordKeys[i],recordValues[i]);
}
predReq.setRecord(record);
predReq.setPredictEndpoint(predictEndpoint);
predRes=amlClient.predict(predReq);
return predRes;
}
Now what is happening is - if i enable the real time prediction by using aws management console manually and then run this segment of code, then the results are generated as expected but when i the realtime prediction is disabled, then i get this error -
Exception in thread "main" com.amazonaws.services.machinelearning.model.PredictorNotMountedException: Either ML Model with id ml-Lkqmcs8
cM2W is not enabled for real-time predictions or the MLModelId is invalid. (Service: AmazonMachineLearning; Status Code: 400; Error Code
: PredictorNotMountedException; Request ID: 2dc70e58-07d0-11e5-a0c7-bb93f17d1b2e)
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1160)
at com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.java:748)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:467)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:302)
at com.amazonaws.services.machinelearning.AmazonMachineLearningClient.invoke(AmazonMachineLearningClient.java:1995)
at com.amazonaws.services.machinelearning.AmazonMachineLearningClient.predict(AmazonMachineLearningClient.java:637)
at com.nrift.aml.prediction.realtime.CreateRealTimePrediction.createRealTimePrediction(CreateRealTimePrediction.java:61)
at RealTimePrediction.main(RealTimePrediction.java:53)
which effectively means that this segment of code is not enabling the real time prediction though i have used
CreateRealtimeEndpoint
api in it.
P.s- the code segment i have posted is a not complete, the complete code is working correctly so you can make assumptions about the correctness of code.
The API you are looking for is CreateRealtimeEndpoint. Creating a real-time endpoint is the mechanism for enabling the model to be used for real-time predictions. When you no longer need to use this model, you can destroy the endpoint with the DeleteRealtimeEndpoint API. The model always stays intact, so you can create/delete endpoints when needed.

Amazon RDS: Launching "db.t1.micro" instances using the JAVA SDK

I'm trying to start a new MySql Instance on Amazon RDS using the Java API and the following code:
CreateDBInstanceRequest createDBInstanceRequest = new CreateDBInstanceRequest();
createDBInstanceRequest.setEngine("MySQL");
createDBInstanceRequest.setLicenseModel("general-public-license");
createDBInstanceRequest.setEngineVersion("5.5.25a");
createDBInstanceRequest.setDBInstanceClass("db.t1.micro");
createDBInstanceRequest.setMultiAZ(false);
createDBInstanceRequest.setAutoMinorVersionUpgrade(true);
createDBInstanceRequest.setAllocatedStorage(5);
createDBInstanceRequest.setDBInstanceIdentifier("mydbinstance");
createDBInstanceRequest.setMasterUsername("master");
createDBInstanceRequest.setMasterUserPassword("password");
createDBInstanceRequest.setDBName("dbname");
createDBInstanceRequest.setPort(3306);
createDBInstanceRequest.setDBParameterGroupName("default.mysql5.5");
createDBInstanceRequest.setDBSubnetGroupName("dev");
createDBInstanceRequest.setBackupRetentionPeriod(1);
DBInstance dbInstance = RDS.createDBInstance(createDBInstanceRequest);
The problem is that this always results in the following error:
AWS Error Code: InsufficientDBInstanceCapacity, AWS Error Message:
Cannot create a database instance because there is no availability
zone with sufficient capacity. Please try your request again at a
later time.
As suggested, I tried at a later time but have never been able to launch a new instance programatically but when I try to launch an instance using the Amazon Mgmt Console, using exactly the same parameters, it launches instantly.
I have also noticed that this problem only occurs with DB Instance Class "db.t1.micro".
Is this instance class not available through the API?
Are you certain this exact version of MySQL is available in any of the availability zones in your region?
I would suggest to execute DescribeOrderableDBInstanceOptions for your engine of choice first, filter using your own criteria (e.g. DBInstanceClass="db.t1.micro") and then select the version from that.

Categories