The function safe_getMetadata() scans a Sentinel2 product (main path or granule xml file) to retrieve information about the product.

The accessory function rm_invalid_safe() remove a SAFE archive in the case it is not recognised by safe_getMetadata().

The accessory function safe_isvalid() scan the SAFE name to understand if it is a valid SAFE.

  info = "all",
  format = "default",
  simplify = TRUE,
  abort = TRUE,
  allow_oldnames = FALSE

rm_invalid_safe(s2, req_res = c("10m", "20m", "60m"), allow_oldnames = FALSE)

  allow_oldnames = FALSE,
  check_file = TRUE,
  req_res = c("10m", "20m", "60m")



Sentinel-2 products, which can be:

  • a list of products in the format safelist (see safelist);

  • a vector of SAFE paths;

  • a vector of paths of xml product files with metadata. If the product does not exist locally, the function can run only with option info = "nameinfo" (see below).


(optional) A character vector with the list of the metadata which should be provided. Accepted values are:

  • "all" (default): all the retrievable metadata are provided;

  • "fileinfo": only the metadata obtained by scanning the file name and product structure (without opening it with GDAL) are provided.

  • "nameinfo": only the metadata obtained by scanning the file name are provided (it is faster and there is no need to have downloaded yet the file).

  • a vector of single specific information (one or more from the followings):

    • "name" (SAFE name - this is always returned);

    • "validname" (TRUE or FALSE);

    • "exists" (TRUE or FALSE);

    • "prod_type" ('singlegranule' or 'product');

    • "version" ('old' or 'compact');

    • "tiles" (vector with the tiles ID available in the product);

    • "utm" (vector with the UTM zones used in the product);

    • "xml_main" (name of the main XML file with metadata);

    • "xml_granules" (names of the XML with granule metadata);

    • "level" ('1C' or '2A');

    • "creation_datetime", "id_tile", "mission", "centre", "file_class", "id_orbit", "orbit_number", "sensing_datetime", "id_baseline": metadata specific of the product type and version (they are returned only if obtainable for the specified input);

    • "clouds", "direction", "orbit_n", "preview_url", "proc_baseline", "level", "sensing_datetime", "nodata_value", "saturated_value": information retrieved from the metadata stored in the XML file;

    • "res": resolutions with all the output products available;

    • "jp2list" (data.frame with the list of the JP2 band files - asking for this info will cause format to be coerced to "list").

    • "offset" (named vector with the offset values of each band - asking for this info will cause format to be coerced to "list").

    Notice that the required info are returned only if available; i.e., if some info requiring existing files are asked by the user, but input SAFE do not exist, only info retrievable by the SAFE name are returned.


Output format, being one of the followings:

  • "data.table" and "data.frame": a table with one row per s2 input and one column per required info;

  • "list": a list (one element per s2 input) in which each element is a list of the required info;

  • "vector": a list (one element per info) in which each element is a named vector (with s2 length and names) with the required info;

  • "default" (default): "vector" if info is of length 1; "data.table" otherwise.


Logical parameter, which applies in case s2 is of length 1: in this case, if TRUE (default) and format is "list" or "vector", a single info list or vector is returned; if FALSE, a list of length 1 (containing the list or vector of the required s2 product) is returned.


Logical parameter: if TRUE (default), the function aborts in case some inputs are not recognised, or if some files do not exists (in case some info elements require the files to be present); if FALSE, a warning is shown.


Logical parameter: if TRUE, old (long) name products are managed (metadata are returned, and they are considered valid; if FALSE (default), they are considered as non-supported files. Note that, from sen2r version 1.1.0, oldname products are no more supported within processing chains, so this function is deprecated and no more supported; moreover, it will be removed in next releases.


Character: vector of variable length (0 to 3) containing the names of the spatial resolution to be checked (one or more among "10m", "20m" and "60m"). In case of level 2A-products, the existence of the JP2 files with the required resolutions necessary for sen2r processing chains (spectral bands and SCL) is checked, determining the result of the check. Default is c("10m","20m","60m"), since Sen2Cor by default produces all of these resolutions. NULL can be used not to scan for JP2 content. In case of level-1C products, in which each layer band is available in a specific resolution, any of the previous values causes all JP2 layers to be checked, while NULL causes no scan to be performed (as in the case of L2A). In safe_isvalid(), this argument is ignored if check_file = FALSE.


Logical: if TRUE (default), the content of the provided paths is checked; if FALSE, only the validity of SAFE names is tested.


safe_getMetadata() returns a data.table, a data.frame or a list (depending on argument format) with the output metadata;

rm_invalid_safe() returns a named vector (with the length of s2) with TRUE if the s2 product was removed, FALSE elsewhere.

safe_isvalid() returns a named vector (with the length of s2) with TRUE if the product is a valid SAFE, FALSE if not.


License: GPL 3.0


L. Ranghetti, M. Boschetti, F. Nutini, L. Busetto (2020). "sen2r": An R toolbox for automatically downloading and preprocessing Sentinel-2 satellite data. Computers & Geosciences, 139, 104473. doi:10.1016/j.cageo.2020.104473 , URL:


Luigi Ranghetti, phD (2019)


# Define product name
s2_examplenames <- c(

# Return the information retrievable from the file names (files are not scanned)
safe_getMetadata(s2_examplenames, info="nameinfo")
#>                                                                 name validname
#> 1: S2A_MSIL1C_20190723T101031_N0208_R022_T32TNS_20190723T121220.SAFE      TRUE
#> 2: S2A_MSIL1C_20190723T101031_N0208_R022_T32TNR_20190723T121220.SAFE      TRUE
#>    prod_type version mission level        sensing_datetime id_baseline id_orbit
#> 1:   product compact      2A    1C 2019-07-23 10:10:31 UTC        0208      022
#> 2:   product compact      2A    1C 2019-07-23 10:10:31 UTC        0208      022
#>    id_tile       creation_datetime
#> 1:   32TNS 2019-07-23 12:12:20 UTC
#> 2:   32TNR 2019-07-23 12:12:20 UTC

# Return some specific information without scanning files
safe_getMetadata(s2_examplenames, info=c("level", "id_tile"))
#>                                                                 name level
#> 1: S2A_MSIL1C_20190723T101031_N0208_R022_T32TNS_20190723T121220.SAFE    1C
#> 2: S2A_MSIL1C_20190723T101031_N0208_R022_T32TNR_20190723T121220.SAFE    1C
#>    id_tile
#> 1:   32TNS
#> 2:   32TNR

# Return a single information without scanning files
# (in this case, the default output is a vector instead than a data.table)
safe_getMetadata(s2_examplenames, info="level")
#> S2A_MSIL1C_20190723T101031_N0208_R022_T32TNS_20190723T121220.SAFE 
#>                                                              "1C" 
#> S2A_MSIL1C_20190723T101031_N0208_R022_T32TNR_20190723T121220.SAFE 
#>                                                              "1C" 

# Check if the products are valid existing SAFE archives
#> S2A_MSIL1C_20190723T101031_N0208_R022_T32TNS_20190723T121220.SAFE 
#>                                                             FALSE 
#> S2A_MSIL1C_20190723T101031_N0208_R022_T32TNR_20190723T121220.SAFE 
#>                                                             FALSE 

# Check if the product names are valid SAFE names
safe_isvalid(s2_examplenames, check_file = FALSE)
#> S2A_MSIL1C_20190723T101031_N0208_R022_T32TNS_20190723T121220.SAFE 
#>                                                              TRUE 
#> S2A_MSIL1C_20190723T101031_N0208_R022_T32TNR_20190723T121220.SAFE 
#>                                                              TRUE 
safe_isvalid("invalid_safe_name.SAFE", check_file = FALSE)
#> invalid_safe_name.SAFE 
#>                  FALSE 

if (FALSE) {
# Download a sample SAFE archive (this can take a while)
s2_exampleurl <- c(
  "S2B_MSIL2A_20220612T100559_N0400_R022_T32TNR_20220612T132443.SAFE" =
s2_download(s2_exampleurl, outdir=tempdir())
s2_examplepath <- file.path(tempdir(), names(s2_exampleurl))

# Return all the available information

# Return some specific information
safe_getMetadata(s2_examplepath, info=c("clouds", "direction"))

# Return a single information
safe_getMetadata(s2_examplepath, info="nodata_value")

# Check if the downloaded SAFE is valid

# Delete it if it is not recognised