Preguntas frecuentes de solución de problemas - AWS SDK for Java 2.x

Preguntas frecuentes de solución de problemas

Cuando utilice AWS SDK for Java 2.x en sus aplicaciones, es posible que se produzcan los errores de tiempo de ejecución que se señalan en este tema. Utilice estas sugerencias como ayuda para descubrir la causa principal y resolver el error.

¿Cómo puedo corregir el error “java.net.SocketException: Connection reset” o “server failed to complete the response”?

Un error de restablecimiento de conexión indica que el host, el Servicio de AWS o cualquier intermediario (por ejemplo, una puerta de enlace de NAT, un proxy o un equilibrador de carga) ha cerrado la conexión antes de que se completara la solicitud. Dado que las causas pueden ser múltiples, es necesario saber por qué se cierra la conexión para encontrar una solución. Los siguientes elementos suelen provocar el cierre de una conexión.

  • La conexión está inactiva.Esto es habitual en las operaciones de streaming, en las que los datos no se escriben ni salen de la red durante un período de tiempo, por lo que un intermediario detecta que la conexión está interrumpida y la cierra. Para evitarlo, asegúrate de que tu aplicación descargue o cargue datos de forma activa.

  • Usted ha cerrado el cliente de HTTP o el SDK. Asegúrese de no cerrar recursos mientras estén en uso.

  • Un proxy configurado incorrectamente. Intente omitir los proxies que haya configurado para comprobar si se soluciona el problema. Si se soluciona el problema, el proxy está cerrando la conexión por alguna razón. Investigue su proxy específico para determinar por qué cierra la conexión.

Si no puede identificar el problema, ejecute un volcado de TCP para una conexión afectada en la periferia del cliente de la red (por ejemplo, después de cualquier servidor proxy que usted controle).

Si ve que el punto de conexión de AWS está enviando un TCP RST (restablecimiento), póngase en contacto con el servicio afectado para ver si puede determinar el motivo del restablecimiento. Prepárese para proporcionar los ID de la solicitud y las marcas de tiempo del momento en que se produjo el problema. El equipo de soporte de AWS también podría beneficiarse de registros de red que muestren exactamente qué bytes envía y recibe su aplicación y cuándo.

¿Cómo puedo corregir “tiempo de espera de conexión”?

Un error de tiempo de espera de conexión indica que el host, el Servicio de AWS o cualquier intermediario (por ejemplo, una puerta de enlace de NAT, un proxy o un equilibrador de carga) no han podido establecer una nueva conexión con el servidor dentro del tiempo de espera de conexión configurado. Los siguientes elementos describen causas comunes de este problema.

  • El tiempo de espera de conexión configurado es demasiado bajo. De forma predeterminada, el tiempo de espera de conexión es de 2 segundos en AWS SDK for Java 2.x. Si establece el tiempo de espera de conexión demasiado bajo, es posible que aparezca este error. El tiempo de espera de conexión recomendado es de 1 segundo si solo hace llamadas dentro de una región y de 3 segundos si realiza solicitudes entre regiones.

  • Un proxy configurado incorrectamente. Intente omitir los proxies que haya configurado para comprobar si se soluciona el problema. Si se soluciona, la razón del problema del tiempo de espera de conexión se encuentra en el proxy. Investigue su proxy específico para determinar la causa

Si no puede identificar el problema, ejecute un volcado de TCP para una conexión afectada en la periferia del cliente de la red (por ejemplo, después de cualquier servidor proxy que usted controle) para investigar posibles problemas de red.

¿Cómo puedo corregir “java.net.SocketTimeoutException: Read timed out”?

Un error de tiempo de espera agotado de lectura indica que la JVM ha intentado leer los datos del sistema operativo subyacente, pero no se devolvieron dentro del tiempo configurado mediante el SDK. Este error puede producirse si el sistema operativo, el Servicio de AWS, la empresa o cualquier intermediario (por ejemplo, una puerta de enlace de NAT, un proxy o un equilibrador de carga) no envía los datos en el tiempo esperado por la JVM. Dado que las causas pueden ser múltiples, es necesario saber por qué no se devuelven los datos para encontrar una solución.

Ejecute un volcado de TCP para una conexión afectada en la periferia del cliente de la red (por ejemplo, después de cualquier servidor proxy que usted controle).

Si ve que el punto de conexión de AWS está enviando un TCP RST (restablecimiento), póngase en contacto con el servicio afectado. Prepárese para proporcionar los ID de la solicitud y las marcas de tiempo del momento en que se produjo el problema. El equipo de soporte de AWS también podría beneficiarse de registros de red que muestren exactamente qué bytes envía y recibe su aplicación y cuándo.

¿Cómo puedo corregir el error “Unable to execute HTTP request: Timeout waiting for connection from pool”?

Este error indica que una solicitud no puede obtener una conexión del grupo en el plazo de tiempo máximo especificado. Para solucionar el problema, le recomendamos que habilite las métricas del cliente del SDK para publicar métricas en Amazon CloudWatch. Las métricas de HTTP pueden ayudar a reducir el problema raíz. Los siguientes elementos describen causas comunes de este error.

  • Filtración de conexión. Puede investigar esto comprobando las métricas de LeasedConcurrency, AvailableConcurrency y MaxConcurrency. Si LeasedConcurrency aumenta hasta alcanzar MaxConcurrency pero no disminuye, es posible que haya una filtración de conexión. Una causa común de filtración es que haya una operación de streaming, como un método getObject de S3, que no se ha cerrado. Recomendamos que la aplicación lea todos los datos del flujo de entrada lo antes posible y cierre el flujo de entrada después. En el siguiente gráfico se muestra el aspecto que podrían tener las métricas del SDK en caso de filtración de conexión.

    Captura de pantalla de las métricas de CloudWatch que muestra una posible filtración de conexión.
  • Falta de grupos de conexiones.Esta situación puede producirse si la tasa de solicitudes es demasiado alta y el tamaño del grupo de conexiones que se ha configurado no puede satisfacer la demanda de las solicitudes. El tamaño predeterminado del grupo de conexiones es 50 y, cuando las conexiones del grupo alcanzan el máximo, el cliente de HTTP pone en cola las solicitudes entrantes hasta que haya conexiones disponibles. En el siguiente gráfico se muestra el aspecto que podrían tener las métricas del SDK en caso de falta de grupos de conexiones.

    Captura de pantalla de las métricas de CloudWatch que muestra qué aspecto podría tener la falta de grupos de conexiones.

    Para mitigar este problema, considere la posibilidad de tomar alguna de estas medidas.

    • Aumente el tamaño del grupo de conexiones.

    • Aumente el tiempo de espera de adquisición.

    • Disminuya la tasa de solicitudes.

    Al aumentar el número máximo de conexiones, el rendimiento del cliente puede aumentar (a menos que la interfaz de red ya esté plenamente utilizada). Sin embargo, con el tiempo es posible que se produzcan limitaciones del sistema operativo en cuanto al número de descriptores de archivos utilizados por el proceso. Si ya utiliza plenamente la interfaz de red o no puede aumentar más el número de conexiones, pruebe a aumentar el tiempo de espera de adquisición. Con este aumento se gana tiempo adicional para las solicitudes de adquisición de una conexión antes de que se agote el tiempo de espera. Si las conexiones no se liberan, se agotará el tiempo de espera de las solicitudes subsiguientes.

    Si no puede corregir el problema utilizando las dos primeras medidas, reduzca la tasa de solicitudes probando las siguientes opciones.

    • Simplifique las solicitudes para que las grandes ampliaciones de tráfico no sobrecarguen al cliente.

    • Aumente la eficiencia de las llamadas a Servicios de AWS.

    • Aumente el número de hosts que envían solicitudes.

  • Los subprocesos de E/S están demasiado ocupados. Esto solo se aplica si utiliza un cliente de SDK asincrónico con NettyNioAsyncHttpClient. Si la métrica AvailableConcurrency no es baja (lo que indica que hay conexiones disponibles en el grupo), pero ConcurrencyAcquireDuration es alta, es posible que se deba a que los subprocesos de E/S no pueden administrar las solicitudes. Asegúrese de no que no está pasando Runnable:run como ejecutor de finalización futura y de realizar una tarea que requiera mucho tiempo en la cadena de finalización futura de la respuesta, ya que puede bloquear un subproceso de E/S. Si no es el caso, considere la posibilidad de aumentar el número de subprocesos de E/S mediante el método eventLoopGroupBuilder. Como referencia, la cantidad predeterminada de subprocesos de E/S para una instancia de NettyNioAsyncHttpClient es el doble del número de núcleos de CPU del host.

  • Alta latencia de establecimiento de comunicación de TLS. Si la métrica AvailableConcurrency está cerca de 0 y LeasedConcurrency es inferior a MaxConcurrency, puede deberse a que sea alta la latencia de establecimiento de comunicación de TLS. En el siguiente gráfico se muestra el aspecto que podrían tener las métricas del SDK en caso de latencia alta del establecimiento de comunicación de TLS.

    Captura de pantalla de las métricas de CloudWatch que podrían indicar una latencia alta del establecimiento de comunicación de TLS.

    En el caso de los clientes HTTP que ofrece el SDK de Java y que no están basados en CRT, pruebe a habilitar los registros de TLS para solucionar problemas de TLS. Para el cliente de HTTP basado en AWS CRT, pruebe a habilitar registros de AWSCRT. Si observa que el punto de conexión de AWS tarda mucho en realizar un establecimiento de comunicación de TLS, póngase en contacto con el servicio afectado.

¿Cómo puedo corregir NoClassDefFoundError, NoSuchMethodError o NoSuchFieldError?

Un NoClassDefFoundError indica que no se ha podido cargar una clase en tiempo de ejecución. Estas son las dos causas más comunes de este error:

  • la clase no existe en la ruta de clases porque falta el JAR o porque hay una versión incorrecta del JAR en la ruta de clases.

  • la clase no se ha podido cargar porque su inicializador estático ha lanzado una excepción.

Del mismo modo, NoSuchMethodError y NoSuchFieldError suelen deberse a una versión de JAR que no coincide. Le recomendamos que siga estos siguientes pasos:

  1. Compruebe sus dependencias para asegurarse de que está usando la misma versión de todos los jar del SDK. Cuando no se encuentra una clase, un método o un campo lo más común es que se deba a que ha actualizado a una nueva versión del cliente pero sigue usando una versión antigua de dependencia “compartida” del SDK. Es posible que la nueva versión del cliente intente usar clases que solo existen en las dependencias “compartidas” del SDK más recientes. Pruebe a ejecutar mvn dependency:tree o gradle dependencies (para Gradle) para verificar que coincidan todas las versiones de la biblioteca del SDK. Para evitar este problema por completo en el futuro, recomendamos utilizar la lista de materiales (BOM) para administrar versiones de los módulos del SDK.

    El siguiente ejemplo muestra un ejemplo de versiones de SDK mixtas.

    [INFO] +- software.amazon.awssdk:dynamodb:jar:2.20.00:compile [INFO] | +- software.amazon.awssdk:aws-core:jar:2.13.19:compile [INFO] +- software.amazon.awssdk:netty-nio-client:jar:2.20.00:compile

    La versión de dynamodb es 2.20.00 y la versión de aws-core es 2.13.19. La versión del artefacto aws-core también debería ser 2.20.00.

  2. Compruebe instrucciones al principio de los registros para ver si una clase no se carga debido a un error de inicialización estática. La primera vez que la clase no se carga, puede generar una excepción diferente y más útil que especifique por qué no se puede cargar la clase. Esta excepción, potencialmente útil, se produce solo una vez, por lo que las instrucciones de registro posteriores solo informarán de que no se ha encontrado la clase.

  3. Compruebe el proceso de implementación para asegurarse de que realmente implementa los archivos JAR necesarios junto con la aplicación. Es posible que esté compilando con la versión correcta, pero el proceso que crea la ruta de clases para su aplicación esté excluyendo una dependencia obligatoria.

¿Cómo puedo corregir un error “SignatureDoesNotMatch” o un error “The request signature we calculated does not match the signature you provided”?

Un error SignatureDoesNotMatch indica que la firma generada por AWS SDK para Java y la firma generada por Servicio de AWS no coinciden. Puede deberse a las causas siguientes.

  • Un proxy o un intermediario modifica la solicitud. Por ejemplo, un proxy o un equilibrador de carga puede modificar un encabezado, una ruta o una cadena de consulta haya firmado el SDK.

  • El servicio y el SDK se diferencian en la forma en que codifican la solicitud cuando cada uno genera la cadena que se va a firmar.

Para solucionar este problema, le recomendamos que habilite el registro de depuración en el SDK. Intente reproducir el error y busque la solicitud canónica que ha generado el SDK. En el registro, la solicitud canónica se etiqueta con AWS4 Canonical Request: ... y la cadena que se va a firmar se etiqueta con AWS4 String to sign: ....

Si no puede habilitar la depuración (por ejemplo, porque solo se puede reproducir en producción), agregue lógica a la aplicación que registra información sobre la solicitud cuando se produzca el error. A continuación, puede usar esa información para intentar replicar el error fuera del entorno de producción en una prueba de integración con el registro de depuración activado.

Una vez recopiladas la solicitud canónica y la cadena de firma, compárelas con la especificación de la versión 4 de AWS Signature para determinar si hay algún problema en la forma en que el SDK ha generado la cadena de firma. Si parece haber algún error, puede crear un informe de depuración de GitHub para AWS SDK para Java.

Si no hay ningún error, puede comparar la cadena de firma del SDK con la cadena de firma que algunos Servicios de AWS devuelven como parte de la respuesta de error (Amazon S3, por ejemplo). Si no está disponible, deberá ponerse en contacto con el servicio afectado para ver qué solicitud canónica y cadena de firma han generado para comparar. Estas comparaciones pueden ayudar a identificar los intermediarios que podrían haber modificado la solicitud o diferencias de codificación entre el servicio y el cliente.

Para obtener más información sobre la firma de solicitudes, consulte Firma de solicitudes de AWS API en la Guía del usuario de AWS Identity and Access Management.

ejemplo de una solicitud canónica
PUT /Example-Bucket/Example-Object partNumber=19&uploadId=string amz-sdk-invocation-id:f8c2799d-367c-f024-e8fa-6ad6d0a1afb9 amz-sdk-request:attempt=1; max=4 content-encoding:aws-chunked content-length:51 content-type:application/octet-stream host:xxxxx x-amz-content-sha256:STREAMING-UNSIGNED-PAYLOAD-TRAILER x-amz-date:20240308T034733Z x-amz-decoded-content-length:10 x-amz-sdk-checksum-algorithm:CRC32 x-amz-trailer:x-amz-checksum-crc32
ejemplo de una cadena de firma
AWS4-HMAC-SHA256 20240308T034435Z 20240308/us-east-1/s3/aws4_request 5f20a7604b1ef65dd89c333fd66736fdef9578d11a4f5d22d289597c387dc713

¿Cómo puedo solucionar el error “java.lang.IllegalStateException: Connection pool shut down”?

Este error indica que el grupo de conexiones HTTP de Apache subyacente estaba cerrado. Puede deberse a las causas siguientes.

  • El cliente del SDK se ha cerrado prematuramente.El SDK solo cierra el grupo de conexiones cuando el cliente asociado está cerrado. Asegúrese de no cerrar recursos mientras estén en uso.

  • Se ha lanzado un java.lang.Error. Errores como OutOfMemoryError provocan que un grupo de conexiones HTTP de Apache se cierre. Examine sus registros para ver si hay rastros de pilas de error. Revise también el código para ver los lugares en los que capta Throwable o Error, pero pasa por alto el resultado que evita que aparezca el error. Si el código no muestra errores, vuelve a escribirlo para que se registre la información. La información registrada ayuda a determinar la causa raíz del error.

  • Ha intentado utilizar el proveedor de credenciales del DefaultCredentialsProvider#create() después de que se cerró. DefaultCredentialsProvider#createdevuelve una instancia singleton, por lo que si está cerrada y el código llama al método resolveCredentials, la excepción se generará una vez que caduquen las credenciales (o el token) en caché.

    Compruebe el código de los lugares donde DefaultCredentialsProvider esté cerrado, como se muestra en los siguientes ejemplos.

    • La instancia de singleton se cierra llamando a DefaultCredentialsProvider#close().

      DefaultCredentialsProvider defaultCredentialsProvider = DefaultCredentialsProvider.create(); // Singleton instance returned. AwsCredentials credentials = defaultCredentialsProvider.resolveCredentials(); // Make calls to Servicios de AWS. defaultCredentialsProvider.close(); // Explicit close. // Make calls to Servicios de AWS. // After the credentials expire, either of the following calls eventually results in a "Connection pool shut down" exception. credentials = defaultCredentialsProvider.resolveCredentials(); // Or credentials = DefaultCredentialsProvider.create().resolveCredentials();
    • Invoque a DefaultCredentialsProvider#create() en un bloque de prueba con recursos.

      try (DefaultCredentialsProvider defaultCredentialsProvider = DefaultCredentialsProvider.create()) { AwsCredentials credentials = defaultCredentialsProvider.resolveCredentials(); // Make calls to Servicios de AWS. } // After the try-with-resources block exits, the singleton DefaultCredentialsProvider is closed. // Make calls to Servicios de AWS. DefaultCredentialsProvider defaultCredentialsProvider = DefaultCredentialsProvider.create(); // The closed singleton instance is returned. // If the credentials (or token) has expired, the following call results in the error. AwsCredentials credentials = defaultCredentialsProvider.resolveCredentials();

    Cree una nueva instancia que no sea singleton llamando a DefaultCredentialsProvider.builder().build() si el código ha cerrado la instancia de singleton y debe resolver las credenciales mediante un DefaultCredentialsProvider.

¿Cómo puedo corregir “Unable to load credentials from any of the providers in the chain AwsCredentialsProviderChain”?

Este error indica que AWS SDK for Java 2.x no ha podido encontrar credenciales de AWS válidas en ninguno de los proveedores de credenciales en la cadena de proveedores predeterminados de credenciales. El SDK busca automáticamente credenciales en un orden específico y este error se produce cuando todos los proveedores de la cadena no proporcionan credenciales válidas.

El mensaje de error completo suele tener este aspecto (se añaden finales de línea y sangrados para mejorar la legibilidad):

Unable to load credentials from any of the providers in the chain AwsCredentialsProviderChain( credentialsProviders=[ SystemPropertyCredentialsProvider(), EnvironmentVariableCredentialsProvider(), WebIdentityTokenCredentialsProvider(), ProfileCredentialsProvider(profileName=default, profileFile=ProfileFile(sections=[])), ContainerCredentialsProvider(), InstanceProfileCredentialsProvider() ]) : [ SystemPropertyCredentialsProvider(): Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId)., EnvironmentVariableCredentialsProvider(): Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId)., WebIdentityTokenCredentialsProvider(): To use web identity tokens, the 'sts' service module must be on the class path., ProfileCredentialsProvider(profileName=default, profileFile=ProfileFile(sections=[])): Profile file contained no credentials for profile 'default': ProfileFile(sections=[]), ContainerCredentialsProvider(): Cannot fetch credentials from container - neither AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment variables are set., InstanceProfileCredentialsProvider(): Failed to load credentials from IMDS.]

Problemas y soluciones comunes

Revise la configuración de sus credenciales

Cuando utiliza el proveedor de credenciales predeterminado (llamando a ServiceClient.create() sin configurar credenciales de forma explícita), el SDK busca credenciales en un orden específico. Revise cómo funciona la cadena de proveedores predeterminados de credenciales para comprender qué fuentes de credenciales comprueba el SDK y en qué orden.

Asegúrese de que el método de configuración de credenciales que desea utilizar esté configurado correctamente en su entorno:

Para instancias de Amazon EC2
  • Compruebe el rol de IAM: compruebe que haya un rol de IAM asociado a la instancia.

  • Fallos intermitentes del IMDS: si se producen fallos intermitentes (que suelen durar unos cientos de milisegundos), suele deberse a problemas transitorios de red que afectan al servicio de metadatos de instancias (IMDS).

    Soluciones:

    • Habilite el registro de depuración para analizar el tiempo y la frecuencia de los fallos

    • Considere la posibilidad de implementar lógica de reintento en la aplicación para errores relacionados con credenciales

    • Compruebe si hay problemas de conectividad de red entre la instancia y el punto de conexión del IMDS

Para entornos de contenedores

Confirme que los roles de tareas (Amazon ECS) o las cuentas de servicio (Amazon EKS) estén configuradas y que las variables de entorno necesarias estén configuradas.

Para desarrollo local

Compruebe que las variables de entorno, los archivos de credenciales o la configuración del Centro de identidades de IAM están definidos.

Para federación de identidades web
  • Compruebe la configuración: compruebe que existe el archivo de token de identidad web y que están configuradas las variables de entorno necesarias.

  • Falta la dependencia del módulo STS: si aparece el error To use web identity tokens, the 'sts' service module must be on the class path, debe agregar el módulo STS como dependencia. Esto es habitual cuando se utiliza Pod Identity de Amazon EKS u otra autenticación de token de identidad web.

    Solución: añada el módulo STS a las dependencias de su proyecto:

    • <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>sts</artifactId> </dependency>

      Para algunos servicios, es posible que también necesite la dependencia de aws-query-protocol:

      <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>aws-query-protocol</artifactId> </dependency>

Problemas de conectividad de red o de proxy

Si aparecen errores Connection refused en la cadena de proveedores de credenciales, suele deberse a problemas de conectividad de red cuando el SDK intenta llegar a los puntos de conexión de AWS.

Soluciones:

  • Compruebe la configuración del proxy si utiliza un servidor proxy

  • Compruebe que la red permita conexiones HTTPS salientes a los puntos de conexión de AWS

  • Habilite registro de depuración para ver los intentos de conexión detallados

  • Pruebe la conectividad mediante herramientas como curl para verificar el acceso de red a los puntos de conexión de AWS